在C#中借助ICSharpCode.SharpZipLib,可实现文件/文件夹的压缩和解压,GitHub下载地址:https://github.com/icsharpcode/SharpZipLib
1.简单压缩
/// <summary>
/// 生成Zip压缩文件
/// </summary>
/// <param name="zipPath">生成压缩包名称</param>
/// <param name="filePath">被压缩文件列表</param>
public void CreateZipFile(string zipPath, List<string> filePath)
{
using (ZipOutputStream zip = new ZipOutputStream(File.Open(zipPath, FileMode.OpenOrCreate)))
{
//循环设置目录下所有文件(支持子目录搜索)
foreach (string file in filePath)
{
if (File.Exists(file))
{
FileInfo item = new FileInfo(file);
FileStream fs = File.OpenRead(item.FullName);
byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 0, buffer.Length);
ZipEntry entry = new ZipEntry(item.Name);
zip.PutNextEntry(entry);
zip.Write(buffer, 0, buffer.Length);
}
}
}
}
2.多级目录的文件夹压缩
/// <summary>
/// 压缩进度委托
/// </summary>
/// <param name="msgid">ID</param>
/// <param name="progress">进度</param>
public delegate void ZipProgressDel(string msgid, double progress);
/// <summary>
/// 压缩进度事件
/// </summary>
public event ZipProgressDel OnZipProgressEvent;
/// <summary>
/// Zip压缩多层目录
/// </summary>
/// <param name="msgId">ID</param>
/// <param name="zipedFile">生成的压缩文件名称</param>
/// <param name="strDirectory">被压缩的目录</param>
public void ZipFileDirectory(string msgId, string zipedFile, string strDirectory)
{
using (System.IO.FileStream ZipFile = System.IO.File.Create(zipedFile))
{
using (ZipOutputStream s = new ZipOutputStream(ZipFile))
{
ZipStep(msgId, strDirectory, s, string.Empty, true);
}
}
}
/// <summary>
/// 递归遍历目录
/// </summary>
/// <param name="msgId">ID</param>
/// <param name="strDirectory">被压缩的目录</param>
/// <param name="s">生成的压缩文件输出流</param>
/// <param name="parentPath">父路径</param>
/// <param name="showProgress">是否显示进度</param>
private void ZipStep(string msgId, string strDirectory, ZipOutputStream s, string parentPath, bool showProgress)
{
if (strDirectory[strDirectory.Length - 1] != Path.DirectorySeparatorChar)
{
strDirectory += Path.DirectorySeparatorChar;
}
Crc32 crc = new Crc32();
string[] filenames = Directory.GetFileSystemEntries(strDirectory);
int finished = 0;
int total = filenames.Count();
foreach (string file in filenames)// 遍历所有的文件和目录
{
if (!this.fileOnlineDic.ContainsKey(msgId))
{
// 发现取消发送后,停止压缩文件
return;
}
if (Directory.Exists(file))// 先当作目录处理如果存在这个目录就递归Copy该目录下面的文件
{
string pPath = parentPath;
pPath += file.Substring(file.LastIndexOf("\\") + 1);
pPath += "\\";
ZipStep(msgId, file, s, pPath, false);
}
else // 否则直接压缩文件
{
//打开压缩文件
using (FileStream fs = File.OpenRead(file))
{
byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 0, buffer.Length);
string fileName = parentPath + file.Substring(file.LastIndexOf("\\") + 1);
ZipEntry entry = new ZipEntry(fileName);
entry.DateTime = DateTime.Now;
entry.Size = fs.Length;
fs.Close();
crc.Reset();
crc.Update(buffer);
entry.Crc = crc.Value;
s.PutNextEntry(entry);
s.Write(buffer, 0, buffer.Length);
}
}
finished++;
if (showProgress && this.OnZipProgressEvent != null)
{
double progress = Convert.ToDouble(100 * finished / total);
this.OnZipProgressEvent(msgId, progress);
}
}
}
3.解压
/// <summary>
/// 解压Zip文件
/// </summary>
/// <param name="zipPath">zip文件路径</param>
/// <param name="targetPath">解压目标路径</param>
public void UnZip(string zipPath, string targetPath)
{
if (!File.Exists(zipPath))
{
LOG.Error("压缩文件不存在,无法解压");
return;
}
if (!Directory.Exists(targetPath))
{
Directory.CreateDirectory(targetPath);
}
//目录结尾
if (!targetPath.EndsWith("\\"))
{
targetPath = new StringBuilder(targetPath).Append("\\").ToString();
}
using (ZipInputStream zip = new ZipInputStream(File.OpenRead(zipPath)))
{
ZipEntry theEntry = null;
while ((theEntry=zip.GetNextEntry()) != null)
{
string directoryName = string.Empty;
string pathToZip = string.Empty;
pathToZip = theEntry.Name;
if (!string.IsNullOrEmpty(pathToZip))
{
directoryName = new StringBuilder(Path.GetDirectoryName(pathToZip)).ToString();
if (!directoryName.EndsWith("\\"))
{
directoryName = new StringBuilder(directoryName).Append("\\").ToString();
}
}
string fileName = Path.GetFileName(pathToZip);
Directory.CreateDirectory(new StringBuilder(targetPath).Append(directoryName).ToString());
if (!string.IsNullOrEmpty(fileName))
{
string filePath = new StringBuilder(targetPath).Append(directoryName).Append(fileName).ToString();
using (FileStream streamWriter = File.Create(filePath))
{
int size = 2048;
byte[] data = new byte[2048];
while (true)
{
size = zip.Read(data, 0, data.Length);
if (size > 0)
streamWriter.Write(data, 0, size);
else
break;
}
streamWriter.Close();
}
}
}
zip.Close();
}
}