【问题标题】:Zip entry name ends in directory separator character but contains dataZip 条目名称以目录分隔符结尾,但包含数据
【发布时间】:2014-07-24 18:52:25
【问题描述】:
System.IO.Compression.ZipFile.ExtractToDirectory(zipPath, extractPath);

在 C# 中使用 ZipFile,我试图从已知位置提取文件,但它会引发以下错误: System.IO.Exception:Zip 条目名称以目录分隔符结尾,但包含数据

我做了一些研究,ExtractToDirectory 在 MSDN 中有解释,但找不到这个错误定义。您能否解释为什么会发生此错误?

来自 MSDN:

IO异常

destinationDirectoryName 指定的目录已经存在。

-或-

存档中的条目名称为空,仅包含空格,或包含至少一个无效字符。

-或-

提取存档条目将创建一个位于由destinationDirectoryName 指定的目录之外的文件。 (例如,如果条目名称包含父目录访问器,则可能会发生这种情况。)

-或-

要提取的存档条目与已从同一存档中提取的条目具有相同的名称。

【问题讨论】:

  • 我猜这基本上意味着存储在 zip 存档中的文件名包含 .. 或以 `` 结尾。你确定你不会以某种方式弄乱路径,例如使用目标路径作为 zip 存档内部路径?
  • 我花了几个小时后发现的一件事是,这个问题与 zip 文件的生成方式有关。为了解决这个问题,我使用 7-zip 生成了 zip 文件。使用 winRar 生成 zip 文件解决了该问题。我仍然不知道它的根本原因。
  • @Mario,这也是我最初的猜测。但是我没有发现有关路径的任何问题(尽管感谢您的评论)。

标签: c# exception extraction zipfile


【解决方案1】:

我的研究表明,当您使用 7-Zip 实用程序使用“超”压缩级别压缩文件时,某些档案无法使用 .NET System.IO.Compression.ZipFile.ExtractToDirectory() 方法解压缩。 错误消息是:Zip 条目名称以目录分隔符结尾,但包含数据。

根据我的观察,只有满足以下3个条件才会出现此错误:

  1. 目标存档很大 - 500MB+(小存档似乎解压得很好)。
  2. 存档的根目录仅包含文件夹(如果您将至少一个文件添加到存档的根目录,它也可以正常解压缩)。
  3. 使用 7-Zip Ultra 压缩。

最后我找到了三个解决这个 7-Zip 错误的方法。

解决方案 1:将至少一个文件添加到存档的根目录(任何虚拟文件或 readme.txt 文件)。

解决方案 2:使用原生 Windows 压缩实用程序(选择文件,右键单击,发送到 -> 压缩文件夹)。

解决方案 3:不要使用 7-Zip Ultra 压缩。

所有这些解决方案都为我解决了这个问题。选择最适合您项目的那个。

【讨论】:

  • 我发现的另一种可能的情况 - 如果您使用 7zip 压缩已安装驱动器上的内容(但在 OSX 上是原生的)。我有一个在 Windows 中工作的 VM,但驱动器在两个操作系统之间共享。解决方案 2 解决了这个特殊问题。
  • 我有一个使用 7z 创建的 .zip 文件,使用选项 -tzip,相当于 -tzip -mm=Deflate -mx=5,即它不使用 7-zip 超压缩。另外,我在档案的底部放置了一个文件。文件 很大,超过 600MB,在 36 个目录中包含 45000 个文件。我在调试器中使用System.IO.Compression.ZipFile.Open 打开了压缩文件。在所有 36 个 dirs 条目中,都以“/”结尾,但只有两个显示非零长度,而这个长度完全没有意义。结果是 System.IO.Compression.ZipFile 无法解压缩文件 - 即 soln 1 & 3 不起作用。
【解决方案2】:

当 ZipArchive 条目以目录分隔符“/”结尾但长度为 != 0 时会发生错误

您可以通过

轻松找到这些条目
zip.Entries.Where(o => o.FullName.EndsWith("/") && o.Length != 0)

【讨论】:

  • 谢谢。我的问题是这个非零长度来自哪里? zip 存档中的所有目录都以“/”结尾,但所有目录的长度都应为 0。偶尔,有些目录的长度不为零,在这种情况下,长度似乎完全没有意义。您是否知道错误出在 7z.exe 生成的存档中,还是出在 System.IO.Compression.ZipFile.Open 上??
  • @DavidI.McIntosh 我无法想象 ZipFile.Open 是如何修改 zip 的内容的。它更有可能是由导致此问题的外部 zip 程序引起的。这应该很容易验证,方法是在 ZipFile.Open 之前制作 zip 文件的副本并将原始文件与打开的文件进行比较以确保它没有被修改。
  • 对不起,我不清楚。通过“故障是否在于System.IO.Compression.ZipFile.Open”,我没有质疑它是否修改了.zip 文件。我们看到System.IO.Compression.ZipFile.Open 在读取 zip 文件时构建的数据结构中的“非零”长度,但我不清楚它是否实际上是文件中的错误数据,或者 System.IO.Compression.ZipFile.Open 是否有一个错误,导致它在内部使用不正确的长度条目构建数据结构。
  • @DavidI.McIntosh 我唯一一次看到问题是由于文件错误。我没有看到.NET 处理数据的任何问题。 zip 文件格式对于识别文件头并使用二进制编辑器验证长度是否非零来说还不错。
【解决方案3】:

我遇到了这个问题,甚至像 sharpZip 这样的包也不起作用。 (问题出现在 TeamCity 和 artefact zip 包中)

使用 SharpCompress(https://www.nuget.org/packages/sharpcompress/) 结束这个解决方案

var archive = ArchiveFactory.Open(model.UserParams.PathToZipFile.FullName);

foreach (var entry in archive.Entries)
{
  if (entry.IsDirectory == false)
  {
   entry.WriteToDirectory(unZipDirectory, new ExtractionOptions() { ExtractFullPath = true, Overwrite = true });
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-28
    • 1970-01-01
    • 1970-01-01
    • 2012-11-12
    • 2011-11-30
    • 2017-08-29
    • 1970-01-01
    相关资源
    最近更新 更多