System.IO.Compression - подсчет количества файлов с помощью ZipFileArchive очень медленный.

Чтобы обновить индикатор выполнения с количеством файлов для извлечения. Моя программа просматривает список Zip-файлов и собирает количество файлов в них. Общее количество составляет примерно 22000 файлов.

Код, который я использую:

    foreach (string filepath in zipFiles)
    {
        ZipArchive zip = ZipFile.OpenRead(filepath);
        archives.Add(zip);
        filesCounter += zip.Entries.Count;
    }

Однако похоже, что zip.Entries.Count выполняет какой-то обход, и для завершения этого подсчета требуется время (несколько минут и многое, многое другое, если подключение к Интернету не очень хорошее).

Чтобы иметь представление о том, насколько это можно улучшить, я сравнил приведенное выше с производительностью 7-Zip. Я взял один из zip-файлов, содержащих ~ 11000 файлов и папок:

  1. 2 секунды на открытие архива 7-Zip.
  2. 1 секунда, чтобы получить свойства файла.
  3. В свойствах я вижу 10016 файлов + 882 папки - это означает, что 7-Zip ~ 3 секунды определяет, что в Zip-файле 10898 записей.

7-Zip Properties

Любая идея, предложение или любой альтернативный метод, который быстро подсчитывает количество файлов, будут оценены.

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

person Juv    schedule 19.05.2020    source источник
comment
Тем, кто помогает, я рекомендую иметь сквиз на stackoverflow.com/questions/61880276/.   -  person mjwills    schedule 19.05.2020
comment
@mjwills - спасибо, это предыдущий пост по этой проблеме, к сожалению, stackoverflow не позволяет вам повторно открыть его после того, как он был связан.   -  person Juv    schedule 19.05.2020
comment
SO позволяет повторно открывать вопросы - если это не было дубликатом. Этот вопрос (и ваш исходный вопрос) - прямая дубликат. Здесь вы просите невозможного. Если вам нужен более быстрый код, вы должны быть готовы к запуску другого кода.   -  person mjwills    schedule 19.05.2020


Ответы (1)


Моя проблема с индикатором прогресса решена путем нового подхода к этому вопросу.

Я просто накапливаю все размеры файлов ZIP, который служит максимальным размером. Теперь для каждого извлеченного отдельного файла я добавляю его сжатый размер к прогрессу. Таким образом, индикатор выполнения не показывает мне количество файлов, он показывает мне несжатый прогресс (например, если в общей сложности у меня есть 4 ГБ для извлечения, а индикатор выполнения - 1/4 зеленого цвета, я знаю, что извлечен 1 ГБ). Похоже на лучшее представление реальности.

foreach (string filepath in zipFiles)
{
    ZipArchive zip = ZipFile.OpenRead(filepath);
    archives.Add(zip);

    // Accumulating the Zip files sizes.
    filesCounter += new FileInfo(filepath).Length; 
}

// To utilize multiple processors it is possible to activate this loop
// in a thread for each ZipArchive -> currentZip!
// :
// :

foreach (ZipArchiveEntry entry in currentZip.Entries) {
    // Doing my extract code here.
    // :
    // :

    // Accumulate the compressed size of each file.
    compressedFileSize += entry.CompressedLength

    // Doing other stuff
    // :
    // :
}

Таким образом, проблема с улучшением производительности zip.Entries.Count все еще не решена, и мне все еще интересно узнать, как решить эту конкретную проблему (что делает 7Zip, чтобы быть таким быстрым - может быть, они используют DotNetZip или другие библиотеки C ++)

person Juv    schedule 19.05.2020