в .Net 4.5 класс System.IO.Compression.ZipArchive получает некоторые обновления.System.IO.Compression.ZipArchive управление памятью
Как можно читать здесь (http://msdn.microsoft.com/en-us/magazine/jj133817.aspx), теперь он должен выполнять «типичные операции, не требующие чтения всего архива в память».
Для тестирования я пытаюсь сжать 10 файлов, каждый размер 200 МБ.
Это хорошо работает, если вы создаете новые почтовые архивы с этим кодом (низкое потребление памяти за весь процесс):
for (int directoryGroupIndex = 0; directoryGroupIndex < directoryGroups.Count; directoryGroupIndex++)
{
String directoryGroupKey = directoryGroups.Keys.ElementAt(directoryGroupIndex);
FileInfo[] directoryGroup = directoryGroups[directoryGroupKey];
String archiveFileName = String.Format("Readed Logfiles{0}", archiveFileExtension);
String archiveFileFullName = Path.Combine(directoryGroupKey, archiveFileName);
FileInfo archiveFile = new FileInfo(archiveFileFullName);
using (FileStream archiveFileStream = new FileStream(archiveFile.FullName, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read))
using (ZipArchive archive = new ZipArchive(archiveFileStream, ZipArchiveMode.Create, false))
{
for (int directoryGroupFileIndex = 0; directoryGroupFileIndex < directoryGroup.Length; directoryGroupFileIndex++)
{
FileInfo file = directoryGroup[directoryGroupFileIndex];
String archiveEntryName = file.Name;
String archiveEntryPath = DateTime.Now.ToString("yyyy-MM-dd");
String archiveEntryFullName = Path.Combine(archiveEntryPath, archiveEntryName);
ZipArchiveEntry archiveEntry = archive.CreateEntryFromFile(file.FullName, archiveEntryFullName, CompressionLevel.Optimal);
}
}
}
Теперь я хочу добавлять новые записи в этот архив. Я оставляю свой код так, как есть, и запускаю его снова. (с новыми файлами внутри корневого каталога). Если я загляну в документальный документ, то я прочитал «Разрешено только создание новых записей в архиве», что все, что я хочу. Поэтому мой код должен быть в порядке.
Результат теперь:
таблица файлов внутри архива перезаписываются (только новые файлы перечислены).
Размер архивного файла вырос (как и старые, все еще там).
Архив поврежден. Вы можете открыть его, но вы не можете декодировать контент.
Если изменить ZipArchiveMode на «ZipArchiveMode.Update» она работает, как ожидалось, но только с небольшими файлами. Файлы, подобные моему, выбрасывают исключение из памяти, поскольку полный архив загружается в память.
Мой вопрос сейчас. Я идиот и делаю это неправильно, это ошибка, или это ошибка дизайна.
Это приводит меня в норму!
Спасибо от германии за помощь Штеффен
Привет, спасибо Питер. Это звучит как хорошее решение. Но, похоже, есть и недостаток дизайна. Потому что должно быть возможно добавить некоторые новые записи в архив, не загружая полный файл в память. Как я писал, если вы попробуете, файл на самом деле не перезаписывается. потому что размер просто растет.Во-вторых, файл поврежден. В-третьих, если вы обновите архив (например, с winrar), он перестроит все файлы (старые и новые). Таким образом, я думаю, что ZipArchive расширяет файл, исправляя правильный путь, но пропустить обновление таблицы файлов для включения существующих файлов. –
«файл не перезаписывается» - это потому, что вы не просили перезаписать файл. Вместо этого используйте 'FileMode.Create', и он будет перезаписан. Существует фундаментальная проблема с простое добавление к архиву .zip, который заключается в том, что есть контрольная сумма, которая должна учитывать _all_ данных в файле. По крайней мере, оригинал должен быть обработан, чтобы сделать это правильно; вы не можете просто добавить к существующему файлу. И что такой инструмент, как WinRAR, может восстановить поврежденный файл, ничего не говорит о том, что должен делать 'ZipArchive'; это просто означает, что WinRAR полезен. –
Благодарим за разъяснение. –