2011-06-06 91 views
1

我想壓縮一個內存流到另一個內存流,所以我可以上傳到其餘的API。 image是包含tif圖像的初始內存流。GZipStream不壓縮?

WebRequest request = CreateWebRequest(...); 
request.ContentType = "application/zip"; 
MemoryStream zip = new MemoryStream(); 
GZipStream zipper = new GZipStream(zip, CompressionMode.Compress); 
image.CopyTo(zipper); 
zipper.Flush(); 
request.ContentLength = zip.Length; // zip.Length is returning 0 
Stream reqStream = request.GetRequestStream(); 
zip.CopyTo(reqStream); 
request.GetResponse().Close(); 
zip.Close(); 

讓我明白了,什麼我寫信給GZipStream將被壓縮並寫入任何數據流被傳遞到它的構造函數。當我將圖像流複製到拉鍊時,它看起來沒有任何實際複製(圖像是200 + MB)。這是我第一次使用GZipStream的經驗,所以很可能我錯過了一些東西,任何建議,不勝感激。

編輯: 是我應該注意的是對我的一個問題,在上面的代碼,image的位置是在流的盡頭......因此,當我打電話image.CopyTo(zipper);什麼也沒有因位置複製。

+0

只是注意:如果您的TIFF格式已經被壓縮了你不會得到非常可觀的成績(大部分是,我認爲)。 – Cameron 2011-06-06 16:45:13

+0

這些是未壓縮的GeoTiffs。另外,我上傳這些圖片的REST API要求上傳爲zip。 – 2011-06-06 16:46:30

回答

3

[編輯:對GZipStream和它的構造ARGS刪除不正確的信息,並與真正答案:)更新]

您複製到拉鍊後,您需要轉移的位置MemoryStream的回零,如拉鍊寫入存儲流的處理進入它的「光標」以及流讀取:

WebRequest request = CreateWebRequest(...); 
request.ContentType = "application/zip"; 
MemoryStream zip = new MemoryStream(); 
GZipStream zipper = new GZipStream(zip, CompressionMode.Compress); 
image.CopyTo(zipper); 
zipper.Flush(); 
zip.Position = 0; // reset the zip position as this will have advanced when written to. 
... 

另一個要注意的是,GZipStream處於不可搜索,那麼調用.Length將拋出異常。

+0

+1,因爲它解釋了GZipStream不可搜索,但MSDN示例在創建後(而不是基礎流)將數據添加到GZip流*中。 OP沒有誤解 – Cameron 2011-06-06 16:53:06

+0

zipper.CopyTo(reqStream)引發異常。拉鍊不能被讀取。 – 2011-06-06 16:55:53

+0

多次閱讀kip的鏈接MSDN文章後,我越看越您的示例......我認爲您誤解了GZipStream越多。 – 2011-06-06 17:00:59

0
+0

除了using語句之外,我沒有看到示例和我正在做什麼之間的區別。我打算在我開始工作時添加使用語句,直到那時我不希望他們對什麼範圍內的內容造成破壞。 – 2011-06-06 16:51:05

+0

調用'Flush()'有什麼問題?這似乎是完全合法的 – Cameron 2011-06-06 16:51:47

0

我對C#及其庫文件一無所知,但我會嘗試首先使用Close而不是(或之後)Flush

(Java的GZipOutputStream有它衝不下去了,直到Java 7中相同的問題)

+0

看來Close()的確是問題所在! zipper.Close()對我來說是缺少的,我相信它對於原始問題是缺少的。看到這個答案:http://stackoverflow.com/questions/6334463/gzipstream-compression-problem-lost-byte – 2013-09-09 06:46:23