2014-10-17 88 views
0

我在下面的代碼中不斷收到一個令人討厭的OutOfMemory異常。C#OutOfMemoryException使用SharpZipLib創建ZipOutputStream

我在壓縮很多小文件(PDF,每個大約1.5mb)。

起初,我收到了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; 
    } 
+0

實現'IDisposible'的每個類都需要放入'using'塊。如果您有支持它的Visual Studio版本,則可以打開靜態代碼分析,以便在您忘記正確執行時發出警告。 – nvoigt 2014-10-17 04:45:09

+0

它並沒有幫助我害怕。 OutOfMemoryException發生在文件循環中。我無法將outputMemStream放入使用中,因爲我將它用作返回。 我試圖使用緩衝區而不是完全寫入文件,但它也沒有幫助,問題不在於我壓縮的每個文件的大小,而是所有文件的總大小。 – Etienne 2014-10-17 04:54:43

+0

您應該創建一個小型的自包含示例。對於我們所知道的,'FmtValidFileName'可以由'throw new OutOfMemoryException();'組成。準備一個人們可以使用最佳實踐來複制和編譯自己的例子,並且這會幫助您更容易。 – nvoigt 2014-10-17 05:00:03

回答

1

與往常一樣,簡潔但很完整的代碼示例將大大有助於幫助你得到好的答案很長的路要走。

也就是說,你可能要考慮在.NET中使用(相對較新的)System.IO.Compression.ZipArchive類。它比第三方庫可能更少錯誤和/或更可靠(儘管我承認SharpZipLib相當受到尊重:))。

更重要的是,您可以使用ZipArchiveMode.Create值實例化新的ZipArchive對象,這會導致壓縮數據直接寫入流而不是緩存在內存中。在這種模式下,不管存在多少數據或嘗試創建多少個歸檔項目,內存不足錯誤都不應該存在。

編輯:還有一件事:爲了確保完全避免內存不足的問題,請確保您使用的任何.zip實現直接寫入磁盤。寫入臨時內存中的MemoryStream當然會對您的進程施加限制,否則不會發生。

+0

謝謝我會嘗試,但我必須問我的代碼示例是什麼?這是既簡潔又完整。 – Etienne 2014-10-17 05:38:25

+0

一個完整的代碼示例是我或其他人可以將其複製到一個空白項目中,然後在不添加_anything_ else的情況下進行編譯和運行的示例。在某些情況下做這種做法很棘手,比如這個例子,因爲這個例子必須包含或生成重現問題所需的測試數據。但是,儘管您的代碼示例非常簡潔,但並不完整。 – 2014-10-17 05:42:43

+0

在StackOverflow中很少看到任何這些,但是足夠公平,我可以完全理解那些願意幫助的人不會花時間在生成必要的輸入以重現我的代碼問題。 – Etienne 2014-10-17 05:46:19