程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> GZipStream實現壓縮以及出現的問題

GZipStream實現壓縮以及出現的問題

編輯:關於C語言

在抓取頁面的過程中,在存儲抓取到的頁面內容的時候我需要先將頁面壓縮再存儲, 為了使用上的方便,采用了2.0下的GZipStream來進行壓縮。

引用如下:

using System.IO;
using System.IO.Compression;
......
public static byte[] Compress(byte[] data)
{
  MemoryStream stream = new MemoryStream();
  GZipStream gZipStream = new GZipStream(stream, CompressionMode.Compress);
  gZipStream.Write(data, 0, data.Length);
  //....暫時先在注釋的位置賣點關子
  return stream.ToArray();
}
public static byte[] Decompress(byte[] data)
{
  MemoryStream stream = new MemoryStream();
  GZipStream gZipStream = new GZipStream(new MemoryStream(data), CompressionMode.Decompress);
  byte[] bytes = new byte[4096];
  int n;
  while ((n = gZipStream.Read(bytes, 0, bytes.Length)) != 0)
  {
    stream.Write(bytes, 0, n);
  }
  return stream.ToArray();
}

上面的代碼使用起來似乎是沒有什麼問題的(如果你不仔細做測試的話), 但是當我對各種大小的頁面進行測試後,發現如果壓縮後byte[]長度<4K,那麼問題出 來了:沒法解壓,解壓函數中Read返回結果總是0。聞一多先生曾經在演講中說“郁 悶啊,郁悶,這是某集團的郁悶,恰恰是微軟的光榮(筆者注:我覺得應該屬於微軟bug )”。

我一度懷疑是不是Decompress函數中的bytes數組長度設置長了,後來把長度設置的很 小,但是解壓後還是那樣,返回0。真想去和蓋茨理論理論。

不過幸運的是,我測試發現了這個4K下限制,所以Google了下“GZipStream  4K”,哈哈,在國外的一論壇 (http://www.dotnetmonster.com/Uwe/Forum.ASPx/dotnet-framework/19787/Problem- with-the-GZipStream-class-and-small-streams)裡面終於找到了答案:原來 GZipStream存取數據的時候是以4K為塊進行存取的。所以在壓縮的時候,在返回 stream.ToArray()前應該先gZipStream.Close()(也就是上面俺賣關子的那裡),原因是 GZipStream是在Dispose的時候把數據完全寫入。你說冤嗎?我明明已經Write了,竟然還 要我再Close才可以。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved