2015-02-06 3 views
4

Я пытаюсь добавить большой видео файл (~ 500MB) к ArchiveEntry, используя этот код:Добавление больших файлов IO.Compression.ZipArchiveEntry бросает OutOfMemoryException Exception

using (var zipFile = ZipFile.Open(outputZipFile, ZipArchiveMode.Update)) 
{ 
    var zipEntry = zipFile.CreateEntry("largeVideoFile.avi"); 
    using (var writer = new BinaryWriter(zipEntry.Open())) 
    { 
     using (FileStream fs = File.Open(@"largeVideoFile.avi", FileMode.Open)) 
     { 
      var buffer = new byte[16 * 1024]; 
      using (var data = new BinaryReader(fs)) 
      { 
       int read; 
       while ((read = data.Read(buffer, 0, buffer.Length)) > 0) 
       { 
        writer.Write(buffer, 0, read); 
       } 
      } 
     } 
    } 
} 

Я получаю ошибку

System.OutOfMemoryException

когда writer.Write называется, alltought я использовал промежуточный буфер ....

Любая идея, как это решить?

+0

Вы можете упростить код, удалив считыватели/писатели и используя stream.copyto. Сомневаюсь, что это исправляет проблему. – CodesInChaos

+0

Взгляните на 'AddEntry (name, stream)' (не закрывайте поток перед вызовом 'Save') и' AddFile (name, nameInFileSystem) ' – CodesInChaos

+0

@CodesInChaos: вы хотите использовать' zipFile.CreateEntryFromFile' -> все еще не работает. Я принял ответ с изменением архитектуры процессора на X64, но неэффективность ZipArchiveEntry стоит указать, когда указан параметр ZipArchiveMode.Update (это приводит к загрузке всего содержимого почтового индекса в памяти) –

ответ

1

Создайте приложение как любой процессор и выполните его на машине x64. Это должно решить проблему. (Или напрямую создайте приложение как x64).

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

+0

Есть ли ссылка на страницу о сжатии, подобном одному (-ю) о плавающей запятой? Вера в то, что просто молния что-то делает его меньше, даже если вы застегиваете то, что уже сжато, кажется, становится все более популярным! –

+0

Я принимаю это как ответ, кажется, сейчас работает. Хотя я укажу на неэффективность класса IO.Compression.ArchiveEntry, который должен загружать все содержимое ZipArchive в память, когда указан «ZipArchiveMode.Update». (ужасно) Из msdn: _ Содержимое всего архива хранится в памяти, и никакие данные не записываются в базовый файл или поток, пока архив не будет удален. _ [msdn] (https://msdn.microsoft.com/ru -us/library/system.io.compression.ziparchivemode (v = vs.110) .aspx) –

+0

Это, вероятно, потому, что сжатие выполняется, когда все данные доступны для повышения эффективности сжатия. –