dotnet/runtime

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

オープン

#1,543 opened on 2016/09/13

 (6 件のコメント) (10 件のリアクション) (0 人の担当者)C# (5,445 件のフォーク)batch import
area-System.IO.Compressionenhancementhelp wantedtenet-performance

Repository metrics

Stars
 (17,886 個のスター)
PR merge metrics
 (平均マージ 12d 11h) (30d で 661 merged PRs)

説明

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.

コントリビューターガイド