C#压缩文件方法 C#如何将文件或文件夹打包成zip

来源:这里教程网 时间:2026-02-21 17:41:53 作者:

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,别用于敏感数据 .NET 自带 ZIP API 足够应付大多数打包需求,但细节决定成败:路径编码、空目录、压缩级别、资源释放——这些地方一疏忽,ZIP 就打不开或解压失败。真正难的不是“怎么压缩”,而是“怎么让别人用任意工具都解得开”。

相关推荐