2014-02-28 59 views
0

我一直在嘗試在我的一個程序中實現壓縮方法。我希望它接受一個流,壓縮它並返回壓縮流(它返回一個流,因爲我希望能夠將該流傳遞給另一個函數,而不必將其保存到文件並在稍後重新讀取) 。我有基於MSDN的例子爲GZipStream工作測試版本,這就是我來到了,當我試圖將其轉換爲以中和返回流:壓縮流

public static Stream compress(Stream fileToCompress) 
{ 
    using (MemoryStream compressedFileStream = new MemoryStream()) 
    { 
     using (GZipStream compressionStream = new GZipStream(compressedFileStream, CompressionMode.Compress)) 
     { 
      fileToCompress.CopyTo(compressionStream); 
      return compressionStream; 
     } 
    } 
} 

返回的流保存到一個文件中(在另一種方法中)導致創建一個0字節的文件(相當有效的壓縮,呵呵?)。

我試過尋找othersolutions,但是我一直沒有找到任何使用流的東西,而且我試圖將運行轉換成相同的問題。

編輯:只是爲了記錄,我已經嘗試使用DeflateStream來獲得相同的結果。

EDIT2:原來是測試程序沒有正確保存。謝謝您的幫助。

回答

2

如果你的目標是要返回流,你需要而不是把它放在using塊。

事情是這樣的:

public static Stream compress(Stream fileToCompress) { 
    MemoryStream compressedFileStream = new MemoryStream(); 
    GZipStream compressionStream = new GZipStream(compressedFileStream, CompressionMode.Compress); 
    fileToCompress.CopyTo(compressionStream); 
    compressionStream.Seek(0, SeekOrigin.Begin); // Reset to stream start. 
    return compressionStream; 
} 

否則,當流離開using塊,它呼籲流Dispose()

編輯:另外,複製後,流「指針」是在結束。您需要將指針重新設置爲開始。在保存之前 - 顯示在這裏。

編輯:刪除所有使用塊。如果您需要發佈流,可以手動完成。

+0

請注意,您的示例實際上關閉了會導致相同的「讀取/寫入處置流」異常的基礎流。 –

+0

我對'MemoryStream'和'GZipStream'的交互作用並不是100%確定的,所以我願意接受。我的編輯刪除使用。 –

+0

感謝您的快速響應。我想我以前曾嘗試過,但沒有奏效。我再次嘗試,只是爲了確保,而且我仍然遇到問題。也@AlexeiLevenkov,它沒有拋出任何異常,它只是返回一個空的流。 – user3299958

0

您可以按照Steven Hansen的建議跳過using/Dispose調用,但使用壓縮數據返回MemoryStream的新副本可能會更乾淨。

public static Stream compress(Stream fileToCompress) 
{ 
    using (MemoryStream compressedFileStream = new MemoryStream()) 
    { 
     using (var compressionStream = new GZipStream(
      compressedFileStream, CompressionMode.Compress)) 
     { 
      fileToCompress.CopyTo(compressionStream); 
     } 
     return new MemoryStream(compressionStream.ToArray()); 
    } 
} 

如果你想保持單一內存流 - 使用調用刪除,不要忘記重新定位流。

var compressedFileStream = new MemoryStream(); 
var compressionStream = new GZipStream(
      compressedFileStream, CompressionMode.Compress); 
fileToCompress.CopyTo(compressionStream); 
// Flush to make sure all data written by compression stream. 
compressionStream.Flush(); 
compressedFileStream.Position = 0; 
return compressedFileStream; 

注意,如果你的文件是非常大的使用臨時文件來存儲壓縮/非壓縮流可能會更快由於MemoryStream使用的內存分配策略 - 嘗試都和措施。