SharpZipLib (ICSharpCode.SharpZipLib) 是成熟、開源、純 .NET 實作的壓縮函式庫,支援 Zip、GZip、BZip2、Tar 等格式,無相依性、部署簡單(單一 DLL),是 .NET 壓縮作業的首選。
Install-Package SharpZipLibusing ICSharpCode.SharpZipLib.Zip;
using ICSharpCode.SharpZipLib.Checksums;
using System.IO;
public static void ZipFile(string sourceFile, string destZip, int compressionLevel = 6, int bufferSize = 4096)
{
if (!File.Exists(sourceFile))
throw new FileNotFoundException($"找不到檔案:{sourceFile}");
using (var fsIn = File.OpenRead(sourceFile))
using (var fsOut = File.Create(destZip))
using (var zipStream = new ZipOutputStream(fsOut))
{
zipStream.SetLevel(compressionLevel); // 0=存儲, 9=最高壓縮
var entry = new ZipEntry(Path.GetFileName(sourceFile))
{
DateTime = DateTime.Now,
Size = fsIn.Length
};
// 計算 CRC32 寫入 Header,相容性更好
var crc = new Crc32();
var buffer = new byte[fsIn.Length];
fsIn.Read(buffer, 0, buffer.Length);
crc.Reset();
crc.Update(buffer);
entry.Crc = crc.Value;
zipStream.PutNextEntry(entry);
zipStream.Write(buffer, 0, buffer.Length);
zipStream.Finish(); // 必須呼叫 Finish() 寫入中央目錄
}
}
public static void ZipDirectory(string sourceDir, string destZip, int compressionLevel = 6)
{
using (var fsOut = File.Create(destZip))
using (var zipStream = new ZipOutputStream(fsOut))
{
zipStream.SetLevel(compressionLevel);
var files = Directory.GetFiles(sourceDir, "*.*", SearchOption.AllDirectories);
foreach (var file in files)
{
var relativePath = file.Substring(sourceDir.Length + 1).Replace('\\', '/');
var entry = new ZipEntry(relativePath)
{
DateTime = File.GetLastWriteTime(file),
Size = new FileInfo(file).Length
};
zipStream.PutNextEntry(entry);
using (var fsIn = File.OpenRead(file))
{
var buffer = new byte[4096];
int bytesRead;
while ((bytesRead = fsIn.Read(buffer, 0, buffer.Length)) > 0)
zipStream.Write(buffer, 0, bytesRead);
}
}
zipStream.Finish();
}
}
public static void UnZip(string zipFile, string destDir, string password = null)
{
if (!File.Exists(zipFile))
throw new FileNotFoundException($"找不到壓縮檔:{zipFile}");
Directory.CreateDirectory(destDir);
using (var fsIn = File.OpenRead(zipFile))
using (var zipStream = new ZipInputStream(fsIn))
{
if (!string.IsNullOrEmpty(password))
zipStream.Password = password;
ZipEntry entry;
while ((entry = zipStream.GetNextEntry()) != null)
{
if (entry.IsDirectory)
{
Directory.CreateDirectory(Path.Combine(destDir, entry.Name));
continue;
}
var fullPath = Path.Combine(destDir, entry.Name);
var directory = Path.GetDirectoryName(fullPath);
if (!string.IsNullOrEmpty(directory))
Directory.CreateDirectory(directory);
using (var fsOut = File.Create(fullPath))
{
var buffer = new byte[4096];
int bytesRead;
while ((bytesRead = zipStream.Read(buffer, 0, buffer.Length)) > 0)
fsOut.Write(buffer, 0, bytesRead);
}
// 可選:還原檔案時間
File.SetLastWriteTime(fullPath, entry.DateTime);
}
}
}
private void btnCompress_Click(object sender, EventArgs e)
{
var files = new[] { @"C:\Data\report.pdf", @"C:\Data\image.png" };
ZipFiles(files, @"C:\Output\archive.zip");
}
private void btnExtract_Click(object sender, EventArgs e)
{
UnZip(@"C:\Output\archive.zip", @"C:\Output\Extracted");
}
ZipOutputStream 必須先呼叫 Finish() 寫入中央目錄,再 Close()(或用 using 自動處理)。zipStream.UseZip64 = UseZip64.Off 並手動編碼。ZipInputStream.Password / ZipOutputStream.Password 僅支援傳統 ZipCrypto,非 AES-256。SharpZipLib API 直覺、效能優異,幾行程式碼即可完成壓縮/解壓縮核心需求。掌握 ZipOutputStream/ZipInputStream 串流模式,配合 using 確保資源釋放,即可輕鬆整合至任何 .NET 專案。