导读:本期聚焦于唐僧创作的《C#怎么用ZipArchive压缩和解压文件夹?完整操作实战指南》,敬请观看详情。把散落各处的日志和报表一次性打成zip包发给客户,不少人都卡在空目录丢失和中文乱码上。ZipArchive作为System.IO.Compression里的标准类,能纯托管代码完成流式打包,不必调用外部exe。本文从创建压缩包写条目讲起,覆盖目录树递归、读取时逐条解压到磁盘、以及用注释修正编码避免文件名乱码。对比第三方库,原生方案体积小、部署简单,适合内部工具与微服务。掌握Entry的Open流操作后,既能压单个文件也能保持层级结构。

在C#项目中处理文件归档时,System.IO.Compression命名空间下的ZipArchive类是最直接的选择。它从.NET Framework 4.5开始内置,不需要引入第三方动态库,就能以流的方式创建或读取zip包。与早期依赖外部命令行工具的方式相比,ZipArchive完全运行在托管代码内,可以更精细地控制每一个条目的压缩级别、文件时间和内容写入过程。

C#怎么用ZipArchive压缩和解压文件夹?完整操作实战指南

使用ZipArchive创建压缩包并写入文件夹

创建zip包的核心思路是先打开一个可写流,再用ZipArchive的Create模式实例化,随后通过CreateEntry方法生成条目。如果要把整个文件夹打包,必须自己递归遍历目录树,因为ZipArchive不会自动把子目录结构展开。每遇到一个文件,就创建对应相对路径的条目,并把文件流复制进条目的Open流里。

需要注意,zip内部条目路径使用正斜杠分隔,而Windows本地路径是反斜杠。在拼接条目名时应当把反斜杠替换成斜杠,否则部分解压软件会识别异常。另外空文件夹在zip里表现为末尾带斜杠的条目,如果业务要求保留目录结构,应当显式创建这种条目。

using System;
using System.IO;
using System.IO.Compression;

public static void ZipFolder(string sourceDir, string zipPath)
{
    if (File.Exists(zipPath))
        File.Delete(zipPath);

    using (FileStream fs = new FileStream(zipPath, FileMode.Create))
    using (ZipArchive archive = new ZipArchive(fs, ZipArchiveMode.Create))
    {
        // 递归写入文件和空目录
        foreach (string file in Directory.GetFiles(sourceDir, "*", SearchOption.AllDirectories))
        {
            string relative = file.Substring(sourceDir.Length).TrimStart('\\');
            string entryName = relative.Replace('\\', '/');
            archive.CreateEntryFromFile(file, entryName);
        }

        foreach (string dir in Directory.GetDirectories(sourceDir, "*", SearchOption.AllDirectories))
        {
            string relative = dir.Substring(sourceDir.Length).TrimStart('\\');
            string entryName = relative.Replace('\\', '/') + "/";
            archive.CreateEntry(entryName);
        }
    }
}

上面的代码利用了CreateEntryFromFile简化文件复制,同时手动补建空目录条目。相对路径计算时用了TrimStart('\\')去掉盘符后的反斜杠,确保条目不以斜杠开头。这种方式在中小型目录打包时性能足够,若文件极多可考虑异步流复制降低内存占用。

从ZipArchive读取并解压到本地磁盘

解压过程与压缩相反,以Read模式打开ZipArchive后遍历Entries集合。每个ZipArchiveEntry都有FullName属性表示包内路径,用这个路径在目标文件夹下重建本地文件即可。由于FullName可能包含多层目录,写入前必须确保父目录存在,否则会抛出目录不存在异常。

在提取条目内容时,应当用entry.Open()获取只读流,再复制到目标文件流。对于那种末尾带斜杠的空目录条目,FullName会以斜杠结束,此时只需创建目录而不写文件。处理完所有条目后,本地结构与压缩前基本一致。

using System;
using System.IO;
using System.IO.Compression;

public static void UnzipToFolder(string zipPath, string destDir)
{
    using (FileStream fs = new FileStream(zipPath, FileMode.Open))
    using (ZipArchive archive = new ZipArchive(fs, ZipArchiveMode.Read))
    {
        foreach (ZipArchiveEntry entry in archive.Entries)
        {
            string destPath = Path.Combine(destDir, entry.FullName);

            if (entry.FullName.EndsWith("/"))
            {
                Directory.CreateDirectory(destPath);
                continue;
            }

            Directory.CreateDirectory(Path.GetDirectoryName(destPath));
            using (Stream src = entry.Open())
            using (FileStream outFs = new FileStream(destPath, FileMode.Create))
            {
                src.CopyTo(outFs);
            }
        }
    }
}

这段代码对空目录做了跳过写文件的处理,并用Path.Combine拼接本地路径。由于Path.Combine在Windows下会自动使用反斜杠,不需要我们手动干预。若解压不可信来源的zip,还应检查FullName是否包含..防止路径穿越,把文件写到目标文件夹之外。

中文文件名乱码与压缩级别控制

默认情况下ZipArchive使用UTF-8编码条目标题,但旧版Windows资源管理器有时按系统本地编码读取,导致中文名乱码。可以在创建条目后显式设置entry.Name或借助注释里的编码标记,不过更稳妥的做法是确保生成环境使用较新的.NET且解压端支持UTF-8。若必须兼容老系统,可考虑第三方库指定传统编码,但原生类本身不直接暴露编码属性。

压缩级别通过CompressionLevel枚举控制,有Optimal、Fastest和NoCompression三种。Optimal体积最小但耗CPU,Fastest速度优先,NoCompression仅存储不压缩,适合已经压缩过的媒体文件。在创建条目时通过CreateEntry重载传入级别即可平衡效率。

using System.IO.Compression;

// 用较快速度压缩单个文件
using (FileStream fs = new FileStream("out.zip", FileMode.Create))
using (ZipArchive archive = new ZipArchive(fs, ZipArchiveMode.Create))
{
    ZipArchiveEntry entry = archive.CreateEntry("数据/报表.txt", CompressionLevel.Fastest);
    using (Stream writer = entry.Open())
    using (FileStream src = new FileStream("C:\\Data\\报表.txt", FileMode.Open))
    {
        src.CopyTo(writer);
    }
}

上述示例把本地C:\Data\报表.txt以Fastest级别写入zip内数据目录。可以看到条目名直接写了正斜杠分隔的层级,这样解压后会自动建立数据文件夹。掌握这些细节后,C#处理zip打包解包就能摆脱外部依赖,在服务器或无界面的服务进程里稳定运行。

C# ZipArchive文件夹打包文件压缩解压修改时间:2026-08-23 20:18:57

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。