在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();
}
}