dotnet/runtime

System.IO.Compression: ZipArchive loads entire file in memory on .Dispose

Open

#1543 aperta il 13 set 2016

Vedi su GitHub
 (6 commenti) (10 reazioni) (0 assegnatari)C# (5445 fork)batch import
area-System.IO.Compressionenhancementhelp wantedtenet-performance

Metriche repository

Star
 (17.886 star)
Metriche merge PR
 (Merge medio 12g 11h) (661 PR mergiate in 30 g)

Descrizione

When you open a ZipArchive in Update mode, the entire zip file will be loaded in memory when the .Dispose method is invoked.

This is because .Dipose calls .WriteFile, which:

  • Calls LoadLocalHeaderExtraFieldAndCompressedBytesIfNeeded for all entries, which loads the compressed data into memory for those entries
  • Sets the size of the .zip archive to 0, by calling _archiveStream.SetLength(0);
  • Writes out all entries one by one.

As a result:

  • A lot of memory is used, the compressed data for each entry is loaded into memory
  • A lot of unnecessary disk I/O is performed, because all entries are written out again, even if they were not modified.

An alternative may be to incrementally update the zip archive, and only update entries which changes.

Guida contributor