C#如何使用SharpZipLib压缩多级目录并保留相对路径

来源:编程网作者:小诸葛头衔:草根站长
导读:本期聚焦于小伙伴创作的《C#如何使用SharpZipLib压缩多级目录并保留相对路径》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《C#如何使用SharpZipLib压缩多级目录并保留相对路径》有用,将其分享出去将是对创作者最好的鼓励。

在C#项目开发中,经常需要将包含多级子目录的文件夹完整打包成压缩文件,同时要求解压后目录结构和原文件夹完全一致,保留所有文件的相对路径。SharpZipLib是一款功能强大的.NET开源压缩库,支持Zip、GZip、Tar等多种压缩格式,能够轻松实现这类需求。

C#如何使用SharpZipLib压缩多级目录并保留相对路径

环境准备

首先需要在项目中引入SharpZipLib库,可以通过NuGet包管理器搜索SharpZipLib进行安装,也可以手动下载对应的DLL文件添加到项目引用中。安装完成后,在代码文件顶部添加对应的命名空间引用:

using ICSharpCode.SharpZipLib.Zip;
using System.IO;

核心实现逻辑

实现多级目录压缩并保留相对路径的核心思路是:遍历目标文件夹下的所有文件和子目录,将每个文件的相对路径作为ZipEntry的名称写入压缩流,这样解压时就会自动还原原有的目录结构。

完整代码实现

以下是完整的压缩方法实现,支持指定源目录、输出压缩文件路径,以及是否包含根目录本身:

/// <summary>
/// 使用SharpZipLib压缩多级目录并保留相对路径
/// </summary>
/// <param name="sourceDir">待压缩的源目录路径</param>
/// <param name="zipFilePath">生成的压缩文件路径</param>
/// <param name="includeRootDir">是否将根目录本身包含在压缩包内</param>
public static void CompressDirectory(string sourceDir, string zipFilePath, bool includeRootDir = false)
{
    // 确保源目录存在
    if (!Directory.Exists(sourceDir))
    {
        throw new DirectoryNotFoundException($"源目录不存在: {sourceDir}");
    }

    // 创建文件流用于写入压缩文件
    using (FileStream fs = new FileStream(zipFilePath, FileMode.Create, FileAccess.Write))
    using (ZipOutputStream zipStream = new ZipOutputStream(fs))
    {
        // 设置压缩级别,0-9,9为最高压缩率
        zipStream.SetLevel(6);

        // 获取源目录的父目录,用于计算相对路径
        string parentDir = Path.GetDirectoryName(sourceDir);
        // 处理根目录名称,用于相对路径拼接
        string rootDirName = Path.GetFileName(sourceDir);

        // 递归压缩目录下的所有文件和子目录
        CompressDirectoryRecursive(sourceDir, parentDir, rootDirName, includeRootDir, zipStream);
        zipStream.Finish();
        zipStream.Close();
    }
}

/// <summary>
/// 递归压缩目录内容
/// </summary>
private static void CompressDirectoryRecursive(string currentDir, string parentDir, string rootDirName, bool includeRootDir, ZipOutputStream zipStream)
{
    // 如果是根目录且需要包含根目录本身,先创建根目录的ZipEntry
    if (includeRootDir && currentDir == Path.Combine(parentDir, rootDirName))
    {
        string rootEntryName = rootDirName + "/";
        ZipEntry rootEntry = new ZipEntry(rootEntryName);
        rootEntry.DateTime = DateTime.Now;
        zipStream.PutNextEntry(rootEntry);
        zipStream.CloseEntry();
    }

    // 处理当前目录下的所有文件
    string[] files = Directory.GetFiles(currentDir);
    foreach (string file in files)
    {
        // 计算文件的相对路径
        string relativePath;
        if (includeRootDir)
        {
            // 相对路径从根目录开始
            relativePath = Path.Combine(rootDirName, file.Substring(parentDir.Length + 1 + rootDirName.Length).TrimStart(Path.DirectorySeparatorChar));
        }
        else
        {
            // 相对路径从根目录下的内容开始
            relativePath = file.Substring(parentDir.Length + 1 + rootDirName.Length).TrimStart(Path.DirectorySeparatorChar);
        }

        // 替换路径分隔符为Zip标准的正斜杠
        relativePath = relativePath.Replace(Path.DirectorySeparatorChar, '/');

        // 创建文件对应的ZipEntry
        ZipEntry entry = new ZipEntry(relativePath);
        entry.DateTime = File.GetLastWriteTime(file);
        zipStream.PutNextEntry(entry);

        // 读取文件内容写入压缩流
        using (FileStream fileStream = new FileStream(file, FileMode.Open, FileAccess.Read))
        {
            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) > 0)
            {
                zipStream.Write(buffer, 0, bytesRead);
            }
        }
        zipStream.CloseEntry();
    }

    // 递归处理子目录
    string[] subDirs = Directory.GetDirectories(currentDir);
    foreach (string subDir in subDirs)
    {
        CompressDirectoryRecursive(subDir, parentDir, rootDirName, includeRootDir, zipStream);
    }
}

代码使用说明

调用上述压缩方法非常简单,只需要传入对应的参数即可:

// 示例:压缩D盘下的TestDir目录,生成压缩文件到D盘根目录,包含根目录本身
string sourceDirectory = @"D:TestDir";
string outputZipPath = @"D:TestDir.zip";
CompressDirectory(sourceDirectory, outputZipPath, true);

关键注意事项

  • 路径分隔符处理:Zip格式标准要求路径使用正斜杠/,因此需要将Windows系统的反斜杠替换为/,否则可能出现解压后路径异常的问题。
  • 压缩级别设置:SetLevel方法支持0到9的压缩级别,级别越高压缩率越高,但压缩耗时也会相应增加,可根据实际需求调整。
  • 相对路径计算:核心是通过源目录的父目录和根目录名称,计算出每个文件相对于源目录的路径,确保写入ZipEntry的名称正确。
  • 资源释放:使用using语句确保文件流和压缩流被正确释放,避免出现文件占用的问题。

常见问题处理

如果压缩后的文件解压后目录层级丢失,通常是因为ZipEntry的名称没有正确设置相对路径,需要检查相对路径的计算逻辑是否正确。如果出现文件写入失败的问题,需要检查目标压缩文件的目录是否有写入权限,以及源文件是否被其他进程占用。

C#SharpZipLib多级目录压缩相对路径保留修改时间:2026-07-14 07:12:27

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