获取一个网页数据返回的编码类型是gzip,我该怎么解压缩

qugui 2005-12-24 05:44:43
我是用HttpWebResponse的GetResponseStream()取得的返回流,但此流是经过gzip编码的,我该如何解开.下了ICSharpCode.SharpZipLib.dll不行.
请高人指点一下.
...全文
786 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
qugui 2005-12-25
  • 打赏
  • 举报
回复
我现在用下面的方法:
public static byte[] Compress(Stream Source)
{
Debug.Assert(null != Source);
Source.Seek(0, SeekOrigin.Begin);
MemoryStream objMem = new MemoryStream();
GZipOutputStream objGzip = new GZipOutputStream(objMem);

const int BUFFER_SIZE = 1024 * 10;
byte[] arrBuffer = new byte[BUFFER_SIZE];
int nGetedCount = 0;
do
{
nGetedCount = Source.Read(arrBuffer, 0, BUFFER_SIZE);
objGzip.Write(arrBuffer, 0, nGetedCount);
} while(nGetedCount>0);
objGzip.Finish();
byte[] arrResult = objMem.ToArray();
objGzip.Close(); //压缩完成后,输出流就会被关闭
objGzip = null;
objMem.Close();
objMem = null;
return arrResult;
}

调用:
Stream ReceiveStream = res.GetResponseStream();

if(res.ContentEncoding=="gzip")
{
//StreamReader sr = new StreamReader( ReceiveStream);
//Char[] read = new Char[256];
//int count = sr.Read( read, 0, 256 );
//while (count > 0)
//{
// String str = new String(read, 0, count);
// strResult += str;
// count = sr.Read(read, 0, 256);
//}
using(StreamWriter sw = new StreamWriter("ata.txt",true))
{
sw.WriteLine(DateTime.Now.ToLongTimeString());
sw.WriteLine(ReceiveStream);

}
//strResult=DeCompress(strResult);
byte [] bt= Compress(ReceiveStream);
Encoding encode = System.Text.Encoding.GetEncoding("big5");
strResult = encode.GetString(bt);

}
返回错误:System.NotSupportedException: 此流不支持查找操作。在Source.Seek(0, SeekOrigin.Begin);
写入文件的信息为:System.Net.ConnectStream
麻烦你看看那里错了?
netmicro 2005-12-25
  • 打赏
  • 举报
回复
HttpWebResponse 里面有个 ContentLength 属性(可能后面有个64,不记得,懒得查资料),以这个为准,直接从 ReceiveStream 里读取字节数组、写入 MemoryStream,写够 ContentLength 个字节之后,MemoryStream.Seek(0, SeekOrigin.Begin) 倒回开头,然后用 GZipInputStream 包装,再解压

不要经过string,不要经过char,只能以byte[]为中介
netmicro 2005-12-25
  • 打赏
  • 举报
回复
你应该直接将 res.GetResponseStream() 传入 GZipInputStream 进行解压缩

或者中间通过 MemoryStream 作缓冲,但是绝对不能通过 string 作缓冲

因为转换成 string 就已经变形了(因为字符编码的问题),然后你还把它当成 Base64 来转成 byte[],绝对乱套了

qugui 2005-12-25
  • 打赏
  • 举报
回复
static public string DeCompress(string comppressedString)
{
int size = 0;
string uncompressString = string.Empty;
StringBuilder sb = new StringBuilder(40960);
int totalLength = 0;
byte[] byteInput = System.Convert.FromBase64String(comppressedString);
byte[] writeData = new byte[4096];
Stream s = new GZipInputStream(new MemoryStream(byteInput));
while(true)
{
size = s.Read(writeData,0,writeData.Length);
if(size > 0)
{
totalLength += size;
sb.Append(System.Text.Encoding.UTF8.GetString(writeData,0,size));
}
else
{
break;
}
}
s.Flush();
s.Close();
return sb.ToString();
}

调用:
部份:
Stream ReceiveStream = res.GetResponseStream();

if(res.ContentEncoding=="gzip")
{
StreamReader sr = new StreamReader( ReceiveStream);
Char[] read = new Char[256];
int count = sr.Read( read, 0, 256 );
while (count > 0)
{
String str = new String(read, 0, count);
strResult += str;
count = sr.Read(read, 0, 256);
}
using(StreamWriter sw = new StreamWriter("ata.txt",true))
{
sw.WriteLine(DateTime.Now.ToLongTimeString());
sw.WriteLine(strResult);

}
strResult=DeCompress(strResult);
netmicro 2005-12-25
  • 打赏
  • 举报
回复
我找到的用GZip的服务器,内容可以解压,但是没有GZip Footer,不知道是不是国际规范

你读取信息的服务器是哪个?告诉我让我好测试一下

---------

不过内容大概就是下面这样的:

// 准备请求

HttpWebRequest request = (HttpWebRequest)
WebRequest.Create("http://gamesir.enorth.com.cn/bbsindex.html");
request.ProtocolVersion = new Version(1, 1);
request.Accept = "*/*";
request.Headers.Add("Accept-Encoding: gzip, deflate");
request.KeepAlive = true;
request.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)";

// 读取回应

HttpWebResponse response = (HttpWebResponse)request.GetResponse();

Console.WriteLine("{0}", response.StatusDescription);
foreach(string key in response.Headers.AllKeys)
{
Console.WriteLine("{0}: {1}", key, response.Headers[key]);
}

// 将回应全部读入一个 MemoryStream:

MemoryStream ms = new MemoryStream();
try
{
Stream res = response.GetResponseStream();
byte[] buffer = new byte[8192];
while (true)
{
int read = res.Read(buffer, 0, 8192);
if (read == 0)
{
// 如果服务器用的是 gzip 的话,只能靠读不出更多数据来判断是否已经读完
Console.WriteLine("Response is terminated due to zero byte reception.");
break;
}
else
{
ms.Write(buffer, 0, read);
}
}
}
catch (Exception e)
{
// 抛出异常也可能表示已经读完
Console.WriteLine("Response is terminated due to exception " + e.Message);
}
finally
{
response.Close();
}
Console.WriteLine("Response has {0} bytes.", ms.Length);

// ms 倒回开头:

ms.Seek(0, SeekOrigin.Begin);

// 用 GZipInputStream 包裹:

GZipInputStream gzip = new GZipInputStream(ms);

// 用 GZipInputStream 读取 ms 的内容并写入 ms2:

MemoryStream ms2 = new MemoryStream();
try
{
byte[] buffer = new byte[1]; // 一点一点读——因为这个服务器的gzip没有Footer,读到结尾的时候会出错,所以为了把最后一个字节都读出来,只能一点一点读

while (true)
{
int read = gzip.Read(buffer, 0, 1);
if (read == 0) break;
ms2.Write(buffer, 0, read);
}
}
catch (Exception e)
{
Console.WriteLine("Exception! " + e.ToString());
}
Console.WriteLine("Unzipped.");

// 将 ms2(解压后的内容)保存到文件

fs = File.Create("response.txt");
ms2.Seek(0, SeekOrigin.Begin);
ms2.WriteTo(fs);
fs.Close();
Console.WriteLine("Written to response.txt.");
Console.ReadLine();
netmicro 2005-12-25
  • 打赏
  • 举报
回复
我想我还是去研究一下Transfer-Encoding: chunked然后再写代码给你看好了
netmicro 2005-12-25
  • 打赏
  • 举报
回复
[返回错误:System.NotSupportedException: 此流不支持查找操作。在Source.Seek(0, SeekOrigin.Begin);]

你还没懂我的意思就开始写代码了

我的意思是,将Response流的内容通通复制到MemoryStream里面(这时候MemoryStream处于写入状态,位置在末尾)

然后将 MemoryStream 倒回开头,准备读取

然后用 GZipInputStream 读 MemoryStream

------------------------

另外,你怎么越改越偏离正道……Response已经GZip了,你还继续Compress?我太佩服你了
marvelstack 2005-12-25
  • 打赏
  • 举报
回复
try
http://hardrock.cnblogs.com/archive/2005/12/23/303209.html
netmicro 2005-12-25
  • 打赏
  • 举报
回复
给我看看你是怎么用 SharpZipLib 的
qugui 2005-12-24
  • 打赏
  • 举报
回复
TO:singlepine(小山)
你的是文件打开,我的是返回流,用不上呀.
qugui 2005-12-24
  • 打赏
  • 举报
回复
我看了一下,他返回的消息中有汉字差不多的字样.而ICSharpCode.SharpZipLib.dll压缩后的是没有这样的字符.
singlepine 2005-12-24
  • 打赏
  • 举报
回复
试试这个
http://dev.csdn.net/develop/article/67/article/63/63929.shtm
netmicro 2005-12-24
  • 打赏
  • 举报
回复
哪个服务器这么恶心……

ICSharpCode.SharpZipLib.dll 怎么不行?

它是我找到的第一个支持GZip加解压的库啊
qugui 2005-12-24
  • 打赏
  • 举报
回复
不发送也一样的,服务器指定用gzip返回.我现在用的是VS2003.
用不到那个类呀!
netmicro 2005-12-24
  • 打赏
  • 举报
回复
发送HTTP请求的时候不要发送
Accept-Encoding: gzip

这样服务器就不会gzip给你了吧?

--------

.NET 2.0 里面有个 System.IO.Compression 命名空间,据说就是处理gzip压缩的,但是我没研究过

111,120

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧