ZipFile.CreateFromDirectory最简打包但无密码/增量/空目录支持;ZipArchive可精细控制但需注意Dispose、UTF-8编码及UseZip64设置;SharpZipLib适用于老框架或AES等高级需求。

用 ZipFile.CreateFromDirectory 打包整个文件夹最简单
这是 .NET 4.5+ 内置方案,无需第三方库,一行代码就能把整个文件夹打成 ZIP。但要注意它不支持密码、不支持增量更新、也不处理空文件夹(会跳过)。
常见错误是路径权限不足或目标 ZIP 已被占用,导致 IOException;另外源路径末尾加不加反斜杠不影响结果,但目标 ZIP 文件路径必须包含完整文件名(如 "output.zip"),不能只写目录。
- 确保源目录存在且可读,目标 ZIP 的父目录存在且可写
- 如果要排除某些子目录或文件,得先复制筛选后的结构到临时目录再压缩
- 不支持中文路径在旧版 Windows 上可能出乱码,建议统一用 UTF-8 编码环境(.NET Core / .NET 5+ 默认支持)
用 ZipArchive 精确控制每个文件的压缩行为
当你需要跳过特定文件、修改压缩级别、添加空目录、或从流写入 ZIP 时,ZipArchive 是唯一选择。它底层更灵活,但也更容易出错——比如忘记调用 Dispose() 会导致 ZIP 文件损坏或被锁住。
典型场景:把多个分散的文件打包,或边生成内容边写入 ZIP(如日志归档)。
- 用
CompressionLevel.Optimal或Faster明确指定压缩强度,默认是Optimal - 添加空目录需手动创建
ZipArchiveEntry,名字以"/"结尾(如"logs/") - 从
FileStream写入时,务必用FileMode.Create,否则可能追加写入导致 ZIP 结构异常
处理中文文件名必须设 UseZip64 = Zip64Option.AsNeeded
默认情况下,ZipArchive 在 .NET Framework 下对中文路径写入 ZIP 后,用 Windows 自带解压工具打开会显示乱码或无法识别。这不是编码问题,而是 ZIP 标准兼容性问题。
根本原因是传统 ZIP 使用 IBM Code Page 437 编码存文件名,而 .NET 默认没启用 ZIP64 扩展和 UTF-8 文件名标记(bit 11 in general purpose bit flag)。解决方法是在创建 ZipArchive 时显式启用:
using (var archive = new ZipArchive(outputStream, ZipArchiveMode.Create, leaveOpen: true))
{
archive.UseZip64 = Zip64Option.AsNeeded;
// … 添加条目
}
注意:UseZip64 在 .NET Core 3.0+ 和 .NET 5+ 中已默认为 AsNeeded,但 .NET Framework 4.5–4.8 仍需手动设置。
第三方库 SharpZipLib 适合老项目或特殊需求
如果你还在维护 .NET Framework 2.0–4.0 项目,或者需要 ZIP 分卷、AES 加密、BZIP2 压缩等高级功能,SharpZipLib 仍是可靠选择。NuGet 包名是 SharpZipLib,不是 ICSharpCode.SharpZipLib(后者是旧命名)。
容易踩的坑是混淆 FastZip 和 ZipOutputStream:前者适合整目录一键压缩,后者适合精细控制流式写入;另外它的默认编码是 System.Text.Encoding.Default,中文需手动设为 Encoding.UTF8 并开启 IsUnicodeText = true。
- 使用
FastZip时,ExcludeFilter接收正则字符串,不是 glob 模式 -
ZipOutputStream.PutNextEntry()必须在写入前调用,且entry.Size要提前设好(流式压缩除外) - 加密 ZIP 只支持传统 ZipCrypto(弱),不支持现代 AES,别用于敏感数据










