Делает ZIP-файл.ExtractToDirectory создает исключение, когда каталог существует?

#c# #.net #.net-core #.net-5

Вопрос:

Согласно документам Microsoft, программа должна выдавать IOException сообщение, если каталог назначения, в котором должен быть извлечен zip-файл, уже существует. Кроме того, в разделе «Примечания» говорится: «Каталог назначения не может уже существовать». Однако,

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

работает нормально (без исключений), даже если output существует в виде каталога. Что-то вроде

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

также работает без исключений. Итак, я пытаюсь понять, почему нет исключений, когда в документах Microsoft четко указано, что они должны быть.

Примечание: Я использую .NET 5.

Комментарии:

1. @PranavHosangadi Согласно документам Microsoft, должно быть исключение, так что да, я спрашиваю, почему его нет.

2. @zaggler Это два отдельных примера

3.@PranavHosangadi операция спрашивает о папке, а не о файлах. Ваша скрипка на самом деле доказывает точку зрения операции. Если вы создадите mytest до первого Extract , код все равно будет работать

4. @PanagiotisKanavos ты прав. Вот скрипка: dotnetfiddle.net/UG0ebI Проблема ОП воспроизводима. (ФУ, этот VTC, как невоспроизводимый, не мой)

Ответ №1:

Похоже на ошибку в документации. Для этого я открыл два выпуска GitHub, один для комментариев к исходному коду и один для страницы документов, созданной на их основе

.NET Core имеет открытый исходный код, что означает, что мы можем проверить фактический исходный код, чтобы узнать, что происходит.

ZIP-файл.ExtractToDirectory фактически вызывает расширения ZipFileExtensions.Метод ExtractToDirectory(архивирование, строка) :

 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);
    }
}
 

В фактическом коде исключение IOException не возникает, если целевой каталог существует, даже если на сайте doc так написано:

 /// <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 , что это стоит за фактическими исходными документами.

Для полноты, внутренний метод ExtractRelativeToDirectory явно рассматривает существующую папку назначения как допустимый случай :

 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);
      ...
 

Акцент на :

// Обратите внимание, что это даст нам хороший DirectoryInfo, даже если имя destinationDirectoryName существует

Комментарии:

1. Я подозревал что-то в этом роде. Спасибо, что проверили. Итак, если это действительно ошибка документа, есть ли способ сообщить об этом в Microsoft?

2. Вы можете сделать лучше, чем это, @bjorn93, в правом верхнем углу должна быть кнопка редактирования , которую вы можете нажать и отредактировать самостоятельно.

3. @HereticMonkey это открывает файл только на Github, он не позволяет вам его редактировать. Однако это хорошее место, чтобы обсудить проблемы. Я уже дд