发布于2026-07-17 阅读(0)
扫一扫,手机访问

用 System.IO.Compression 压缩文件为 ZIP 是最轻量、无需第三方库的方案,但默认不支持密码保护和分卷,且对中文路径需额外处理编码问题。这一点,很多初次接触的同学容易忽略。
ZipFile.CreateFromDirectory 批量压缩整个文件夹这算是最省事的方案了,适合打包一个完整目录。它内部自动处理文件遍历、时间戳、目录结构,一调用就完事。但几个限制得心里有数:
DirectoryNotFoundException。CompressionLevel.Optimal、Faster 或 NoCompression,不能设为自定义值,灵活性有限。ZipArchive 手动控制编码了。using System.IO.Compression; ZipFile.CreateFromDirectory(@"C:\myfolder", @"C:\output.zip", CompressionLevel.Optimal, includeBaseDirectory: false);
ZipArchive 精确控制单个文件/子路径压缩当需要跳过某些文件、重命名 ZIP 内路径、添加空目录,或统一设置编码时,ZipArchive 是唯一选择。它底层更灵活,但同时也要自己管理 ZipArchiveEntry 的创建与流写入,工作量稍微大一些。
ZipArchive 时必须传入可写的 FileStream,且 lea veOpen: false 更安全,避免文件句柄泄漏。archive.CreateEntry 的第一个参数是 ZIP 内部路径,支持斜杠分隔的子目录形式,比如 "docs/readme.txt",但不能以 / 开头。entry.Open() 获取的流来完成,且必须完全写完再 Dispose,否则条目会损坏。ZipArchive 时传入 new ZipArchiveOptions { CodePage = 65001 }(仅 .NET 6+ 支持)。using (var fs = File.Create(@"C:\custom.zip"))
using (var archive = new ZipArchive(fs, ZipArchiveMode.Create, lea veOpen: false))
{
var entry = archive.CreateEntry("config/appsettings.json");
using (var entryStream = entry.Open())
using (var fileStream = File.OpenRead(@"D:\appsettings.json"))
{
fileStream.CopyTo(entryStream);
}
}
includeBaseDirectory: false如果误用 ZipFile.CreateFromDirectory 去“压缩一个文件”,常见做法是把它放进临时文件夹再压缩——这时若忘记设 includeBaseDirectory: false,ZIP 里就会多一层文件夹,比如 temp\myfile.txt 而非直接 myfile.txt,使用起来很不方便。
CreateFromDirectory,改用 ZipArchive 直接添加单文件(见上一节)。CreateFromDirectory,务必确保临时目录下只有目标文件,且调用时显式传 includeBaseDirectory: false。必须警惕的是,ZipFile.ExtractToDirectory 和 ZipArchive.ExtractAll 默认不做路径校验。恶意 ZIP 若包含 ../../../etc/passwd 这类路径,可能覆写系统文件。这不是 .NET 的 bug,而是 ZIP 规范允许任意路径,防御责任在使用者身上。
ZipArchiveEntry.FullName 调用 Path.GetFullPath,并检查是否仍落在目标解压目录内。Path.IsPathRooted(entry.FullName) 快速拦截绝对路径,再用 entry.FullName.Contains("..") 做初步筛查(注意跨平台路径分隔符)。entry.Name,它只返回最后一段,无法反映完整路径结构。真正麻烦的,往往不是压的过程,而是压完之后,别人能不能正常解压、文件名会不会乱码、有没有人故意塞个超长路径来搞事情——这些细节不写进代码里,上线后就是事故。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8