You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用C#的ZipArchive创建zip压缩包时是否可以保留原目录结构?

这个需求完全可以实现,你当前的写法没有保留目录结构的原因是ZipArchive.CreateEntryFromFile方法的第二个参数指定的是文件在压缩包内的完整路径,你目前只传入了item.Name(仅文件名),因此所有文件都会被直接存放在压缩包的根目录,不会携带原有目录结构。

方案1:保留文件相对于指定公共根目录的路径(最常用)

这种场景适合你打包的所有文件都归属同一个上层公共目录,最终压缩包内只会保留该根目录以下的层级结构,不会暴露完整的绝对路径,修改后的代码如下:

public static void CreateZipFile(IEnumerable<FileInfo> files, string archiveName, string rootDirectory)
{
    // 统一处理根目录路径,确保末尾带路径分隔符,避免前缀截取错误
    var processedRoot = Path.GetFullPath(rootDirectory).TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar) + Path.DirectorySeparatorChar;
    
    using (var stream = File.OpenWrite(archiveName))
    using (var archive = new ZipArchive(stream, ZipArchiveMode.Create))
    {
        foreach (var item in files)
        {
            // 计算文件相对于根目录的路径,作为压缩包内的条目路径
            var entryPath = item.FullName.Substring(processedRoot.Length);
            archive.CreateEntryFromFile(item.FullName, entryPath, CompressionLevel.Optimal);
        }
    }
}

调用示例:如果你所有待打包文件都在D:\Project\Resource目录下,调用时传入该路径作为第三个参数即可,压缩包内会自动保留Resource目录下的子目录层级。

方案2:保留文件的完整绝对路径

如果你需要在压缩包内保留文件的完整绝对路径(比如C:\Docs\Note\a.txt会完整存到压缩包内),直接修改第二个参数为item.FullName即可:

public static void CreateZipFile(IEnumerable<FileInfo> files, string archiveName)
{
  using (var stream = File.OpenWrite(archiveName))
  using (var archive = new ZipArchive(stream, ZipArchiveMode.Create))
  {
    foreach (var item in files)
    {
      archive.CreateEntryFromFile(item.FullName, item.FullName, CompressionLevel.Optimal);
    }
  }
}

补充说明

  • 如果你传入的文件来自多个完全不相关的根目录,没有公共父级,建议你自定义每个文件在压缩包内的映射路径,避免目录混乱。
  • 路径分隔符在Zip规范中兼容正斜杠和反斜杠,无需额外转换,Windows和其他系统解压都能正常识别目录结构。

内容的提问来源于stack exchange,提问作者ErocM

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 00:27:02