【问题标题】:Does ZipFile.ExtractToDirectory throw an exception when the directory exists?目录存在时 ZipFile.ExtractToDirectory 会抛出异常吗?
【发布时间】:2021-06-02 13:57:19
【问题描述】:

根据Microsoft Docs,如果要提取zip文件的目标目录已经存在,程序应该抛出IOException。此外,“备注”部分说,“目标目录不能已经存在。”然而,

ZipFile.ExtractToDirectory("archive.zip", ".\\output");

即使output 作为目录存在也可以正常工作(没有例外)。类似的东西

ZipFile.ExtractToDirectory("archive.zip", "\\");

也可以毫无例外地工作。因此,我试图理解为什么在 Microsoft Docs 明确建议应该有例外时没有例外。

注意:我正在运行 .NET 5。

【问题讨论】:

  • @PranavHosangadi 根据 Microsoft Docs,应该有一个例外,所以是的,我问为什么没有。
  • @zaggler 这是两个不同的例子
  • @PranavHosangadi OP 询问的是 文件夹,而不是文件。你的小提琴实际上证明了OP的观点。如果您在第一个 Extract 之前创建 mytest,代码仍然有效
  • @PanagiotisKanavos 你是对的。这是小提琴:dotnetfiddle.net/UG0ebI OP 的问题是可重现的。 (FWIW,VTC 不可重现不是我的)

标签: c# .net .net-core .net-5


【解决方案1】:

看起来像一个文档错误。我为此打开了两个 GitHub 问题,one for the source code commentsone for the docs page 是由它们创建的

.NET Core 是开源的,这意味着我们可以检查实际的源代码以了解发生了什么。

ZipFile.ExtractToDirectory实际上调用了ZipFileExtensions.ExtractToDirectory(ZipArchive, String)方法:

public static void ExtractToDirectory(string sourceArchiveFileName, string destinationDirectoryName, Encoding? entryNameEncoding, bool overwriteFiles)
{
    if (sourceArchiveFileName == null)
        throw new ArgumentNullException(nameof(sourceArchiveFileName));

    using (ZipArchive archive = Open(sourceArchiveFileName, ZipArchiveMode.Read, entryNameEncoding))
    {
        archive.ExtractToDirectory(destinationDirectoryName, overwriteFiles);
    }
}

the actual code IOException 中如果目标目录存在则抛出,即使文档网站这么说:

/// <exception cref="IOException">An archive entry?s name is zero-length, contains only whitespace, or contains one or more invalid
/// characters as defined by InvalidPathChars. -or- Extracting an archive entry would have resulted in a destination
/// file that is outside destinationDirectoryName (for example, if the entry name contains parent directory accessors).
/// -or- An archive entry has the same name as an already extracted entry from the same archive.</exception>
public static void ExtractToDirectory(this ZipArchive source, string destinationDirectoryName, bool overwriteFiles)
{
    if (source == null)
        throw new ArgumentNullException(nameof(source));

    if (destinationDirectoryName == null)
        throw new ArgumentNullException(nameof(destinationDirectoryName));

    foreach (ZipArchiveEntry entry in source.Entries)
    {
        entry.ExtractRelativeToDirectory(destinationDirectoryName, overwriteFiles);
    }
}

看起来docs.microsoft.com 位于实际源文档的后面。

为了完整起见,internal ExtractRelativeToDirectory method 明确将现有目标文件夹视为有效案例:

internal static void ExtractRelativeToDirectory(this ZipArchiveEntry source, string destinationDirectoryName, bool overwrite)
{
    if (source == null)
        throw new ArgumentNullException(nameof(source));

    if (destinationDirectoryName == null)
        throw new ArgumentNullException(nameof(destinationDirectoryName));

    // Note that this will give us a good DirectoryInfo even if destinationDirectoryName exists:
    DirectoryInfo di = Directory.CreateDirectory(destinationDirectoryName);
      ...

强调:

// 请注意,即使destinationDirectoryName 存在,这也会为我们提供良好的DirectoryInfo

【讨论】:

  • 我在怀疑这样的事情。感谢您的检查。那么,如果这确实是一个文档错误,有没有办法向 Microsoft 报告?
  • 你可以做得更好,@bjorn93,应该有一个Edit button in the upper right corner你可以自己点击编辑。
  • @HereticMonkey 这只会在 Github 上打开文件,它不允许您实际编辑它。不过,这是一个打开问题的好地方。我已经dd了
猜你喜欢
  • 2018-03-25
  • 2011-11-02
  • 1970-01-01
  • 2011-03-12
  • 1970-01-01
  • 2011-07-12
  • 2013-05-24
  • 2018-08-17
  • 2010-09-26
相关资源
最近更新 更多