0

次のコードで非常に厄介な OutOfMemory 例外が発生し続けます。

たくさんの小さなファイル (PDF、それぞれ約 1.5 MB) を圧縮しています。

最初は、25 個のファイルを圧縮した後に例外が発生していましたが、これは大規模なアーカイブのようには見えません。

ZipEntry のサイズを設定すると、最大 110 個のファイルを圧縮できるようになったので、何とか助けられました (Visual Studio でデバッグしています)。

これが私のコードです。おそらく何か問題があります。

どんな助けでも大歓迎です。

ありがとう

    public static MemoryStream Zip(Dictionary<string, byte[]> files)
    {
        var outputMemStream = new MemoryStream();

        var zipStream = new ZipOutputStream(outputMemStream);

        zipStream.SetLevel(9);
        foreach (var file in files)
        {
            zipStream.PutNextEntry(new ZipEntry(file.Key.FmtValidFileName())
                {
                    Size = file.Value.Length
                });
            zipStream.Write(file.Value, 0, file.Value.Length);
            zipStream.Flush();
        }           
        zipStream.Finish();
        outputMemStream.Position = 0;
        return outputMemStream;
    }
4

2 に答える 2

2

いつものように、簡潔だが完全なコード例は、適切な回答を得るのに大いに役立ちます。

そうは言っても、(比較的新しい)System.IO.Compression.ZipArchiveクラスを .NET で使用することを検討することをお勧めします。サードパーティのライブラリよりもバグが少なく、信頼性が高い可能性があります(ただし、SharpZipLibはかなり尊敬されています:))。

ZipArchiveさらに重要なことは、値を使用して新しいオブジェクトをインスタンス化できることZipArchiveMode.Createです。これにより、圧縮されたデータがメモリ内にキャッシュされるのではなく、ストリームに直接書き込まれます。このモードでは、作成しようとしているデータやアーカイブ アイテムの数に関係なく、メモリ不足エラーは発生しません。

EDIT:もう1つ:メモリ不足の問題を完全に防ぐために、使用している.zip実装が何であれ、ディスクに直接書き込むようにしてください。もちろん、一時的なインメモリへの書き込みは、MemoryStreamそうでなければ発生する必要のないプロセスに制限を課します。

于 2014-10-17T05:35:46.133 に答える
0

16 GB のメモリを搭載した 64 ビット システムを使用しているにもかかわらず、MemoryStream の使用をあきらめました。

私が見つけた関連トピックは次のとおりです: MemoryStream の設定中に OutOfMemoryException: 16GB システムで 256MB 割り当て

また、メモリの代わりに一時ファイルを使用してデータの書き込み/読み取りを行います。

于 2014-10-17T08:23:23.593 に答える