c#使用DotNetZip封装类操作zip文件(创建/读取/更新)实例
下载地址在这里:http://dotnetzip.codeplex.com/
下载到的包里有很多个dll文件,一般引用ionic.zip.dll就可以:
然后引用这个命名空间:
using ionic.zip;
以下是我自己封装的一个类:
/// <summary>
/// zip操作基于 dotnetzip 的封装
/// </summary>
public static class ziputils
{
/// <summary>
/// 得到指定的输入流的zip压缩流对象【原有流对象不会改变】
/// </summary>
/// <param name="sourcestream"></param>
/// <returns></returns>
public static stream zipcompress(stream sourcestream, string entryname = "zip")
{
memorystream compressedstream = new memorystream();
if (sourcestream != null)
{
long sourceoldposition = 0;
try
{
sourceoldposition = sourcestream.position;
sourcestream.position = 0;
using (zipfile zip = new zipfile())
{
zip.addentry(entryname, sourcestream);
zip.save(compressedstream);
compressedstream.position = 0;
}
}
catch
{
}
finally
{
try
{
sourcestream.position = sourceoldposition;
}
catch
{
}
}
}
return compressedstream;
}
/// <summary>
/// 得到指定的字节数组的zip解压流对象
/// 当前方法仅适用于只有一个压缩文件的压缩包,即方法内只取压缩包中的第一个压缩文件
/// </summary>
/// <param name="sourcestream"></param>
/// <returns></returns>
public static stream zipdecompress(byte[] data)
{
stream decompressedstream = new memorystream();
if (data != null)
{
try
{
memorystream datastream = new memorystream(data);
using (zipfile zip = zipfile.read(datastream))
{
if (zip.entries.count > 0)
{
zip.entries.first().extract(decompressedstream);
// extract方法中会操作ms,后续使用时必须先将stream位置归零,否则会导致后续读取不到任何数据
// 返回该stream对象之前进行一次位置归零动作
decompressedstream.position = 0;
}
}
}
catch
{
}
}
return decompressedstream;
}
/// <summary>
/// 压缩zip文件
/// 支持多文件和多目录,或是多文件和多目录一起压缩
/// </summary>
/// <param name="list">待压缩的文件或目录集合</param>
/// <param name="strzipname">压缩后的文件名</param>
/// <param name="isdirstruct">是否按目录结构压缩</param>
/// <returns>成功:true/失败:false</returns>
public static bool compressmulti(list<string> list, string strzipname, bool isdirstruct)
{
try
{
using (zipfile zip = new zipfile(encoding.default))//设置编码,解决压缩文件时中文乱码
{
foreach (string path in list)
{
string filename = path.getfilename(path);//取目录名称
//如果是目录
if (directory.exists(path))
{
if (isdirstruct)//按目录结构压缩
{
zip.adddirectory(path, filename);
}
else//目录下的文件都压缩到zip的根目录
{
zip.adddirectory(path);
}
}
if (file.exists(path))//如果是文件
{
zip.addfile(path);
}
}
zip.save(strzipname);//压缩
return true;
}
}
catch (exception)
{
return false;
}
}
/// <summary>
/// 解压zip文件
/// </summary>
/// <param name="strzippath">待解压的zip文件</param>
/// <param name="strunzippath">解压的目录</param>
/// <param name="overwrite">是否覆盖</param>
/// <returns>成功:true/失败:false</returns>
public static bool decompression(string strzippath, string strunzippath, bool overwrite)
{
try
{
readoptions options = new readoptions();
options.encoding = encoding.default;//设置编码,解决解压文件时中文乱码
using (zipfile zip = zipfile.read(strzippath, options))
{
foreach (zipentry entry in zip)
{
if (string.isnullorempty(strunzippath))
{
strunzippath = strzippath.split('.').first();
}
if (overwrite)
{
entry.extract(strunzippath, extractexistingfileaction.overwritesilently);//解压文件,如果已存在就覆盖
}
else
{
entry.extract(strunzippath, extractexistingfileaction.donotoverwrite);//解压文件,如果已存在不覆盖
}
}
return true;
}
}
catch (exception)
{
return false;
}
}
}
使用方法:
1.压缩文件
list<string> list = new list<string>();
list.add(@"d:\test\ss");
list.add(@"d:\test\test1.jpg");
list.add(@"d:\公司文件.txt");
list.add(@"d:\test\ss.xml");
bool issuc =ziputils. compressmulti(list, "d:\\test2.zip",true);
2.解压文件
bool issuc = ziputils.decompression("d:\\test\\test1.zip", "d:\\teest", true);