2017-02-10 1 views
1

Я создаю хорошее программное обеспечение с использованием C#. Целевая версия: .net 4.5. Одной из основных задач является создание списка файлов (содержащихся в различных каталогах и подкаталогах внутри корневой папки), а затем zip, затем по одному..net 4.5 ZipArchive - утечка памяти в моем программном обеспечении или в библиотеке?

Я использую ZipArchive класс, содержащийся внутри System.IO.Compression;

Вот код:

// STEP 1 

      using (var fs = new FileStream(destination_path + "\\" + zipname + ".zip", FileMode.OpenOrCreate)) 
      { 

       using (var zip = new ZipArchive(fs, ZipArchiveMode.Update)) 
       {     

        // Some non important thing 

        foreach (string single_file in list_file_tobackup) 
        { 
         // non important things 

         zip.CreateEntryFromFile(single_file, temp); 

        } 
       } 

      }  
// STEP 2 

Это маленький кусочек кода, который я нашел вокруг на SO. Важно сказать (возможно), что этот код содержится внутри метода, содержащегося в статическом классе, и вызывается из окна WPF. Весь список, используемый внутри этого кода, представляет собой статический частный список, объявленный в статическом классе, поэтому они останутся в памяти.

В чем проблема?

Когда программное обеспечение находится в начале (ШАГ 1), оно оказывает очень незначительное влияние на память (как и все нормальное малое программное обеспечение). После того, как весь файл был заархивирован, и он, наконец, достигнет конца (ШАГ 2), программное обеспечение взяло БОЛЬШОЙ набор бункера и НИКОГДА не освобождает его.

Если я попытаюсь закрепить очень большую папку (около 400 МБ), программа возьмет и сохранит (даже когда метод закончен) почти 1 ГБ в ОЗУ! Если я попробую какую-то большую папку, это просто сбой (System.OutOfMemoryException).

Программное обеспечение может освобождать память, только если я запустил метод с небольшой папкой.

Сначала я думал, что утечка памяти вызвана большим списком файлов, хранящихся в памяти. Затем я использовал инструменты тестирования памяти Visual Studio, и я обнаружил, что весь этот большой кусок памяти принадлежит классу ZipArchive, поэтому я не могу отлаживать более глубоко.

Я делаю что-то неправильно или просто библиотека ZipAchive недостаточно хороша для того, что я должен делать?

Если это последний: существует ли какая-то лучшая библиотека .zip, которую можно использовать без чрезмерного ограничения лицензии?

+1

Метод Zip Update будет хранить старые и новые файлы, которые могут объяснять утечку памяти. – jdweng

ответ

0

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

Вы пытались использовать ZipArchiveMode.Create?

Если вам необходимо выполнить обновление существующего архива, вы все равно можете использовать Create, скопировав существующий архив и создайте новые записи.

+0

Использование ZipArchiveMode.Create работает! Все файлы добавляются без проблем. К сожалению, программное обеспечение полностью сломано: фрагмент в моем вопросе находится внутри цикла foreach, поэтому во второй раз, когда я его запустил, он просто перезапишет предыдущий zip ... Я не запомнил последнюю фразу, можете ли вы объяснить это лучше? Как я могу сделать больше экземпляра ZipArchiveMode.Create для «обновления» zip-файла, имеющего в конце только один .zip-файл со всем моим контентом? Я думаю, что это невозможно... –

+0

В зависимости от вашего варианта использования каждый раз создание нового архива и просто перезапись предыдущего - это один из вариантов и самый простой. Если вы пытаетесь закрепить очень большой каталог, содержащий большое количество файлов, я бы экспериментировал, создав второй файл архива (в основном, копию) и попытаюсь скопировать записи zip, если файл не изменился и добавить новые. Однако для этого требуется выполнение функции diff и т. Д. – Blackfield

Смежные вопросы