61

当请求使用 Gzip 压缩的页面时,我收到很多以下错误:

System.IO.InvalidDataException:GZip 页脚中的 CRC 与从解压缩数据计算的 CRC 不匹配

我正在使用本机 GZipStream 解压缩并正在考虑解决此问题。考虑到这一点,是否有解决这个或另一个 GZip 库(免费?)的解决方法,可以正确处理这个问题?

我正在验证 webResponse ContentEncoding 是 GZIP

更新 5/11 一个简化的代码片段

//Caller
public void SOSampleGet(string url) 
{
    // Initialize the WebRequest.
    webRequest = (HttpWebRequest)WebRequest.Create(url);
    webRequest.Method = WebRequestMethods.Http.Get;
    webRequest.KeepAlive = true;
    webRequest.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
    webRequest.Headers.Add("Accept-Encoding", "gzip,deflate");
    webRequest.Referer = WebUtil.GetDomain(url);

    HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();    

    using (Stream stream = GetStreamForResponse(webResponse, READTIMEOUT_CONST))
    {
        //use stream
    }
}

//Method
private static Stream GetStreamForResponse(HttpWebResponse webResponse, int readTimeOut)
{
    Stream stream;
    switch (webResponse.ContentEncoding.ToUpperInvariant())
    {
        case "GZIP":
            stream = new GZipStream(webResponse.GetResponseStream(), CompressionMode.Decompress);
            break;
        case "DEFLATE":
            stream = new DeflateStream(webResponse.GetResponseStream(), CompressionMode.Decompress);
            break;

        default:
            stream = webResponse.GetResponseStream();
            stream.ReadTimeout = readTimeOut;
            break;
        }    
    return stream;
}
4

6 回答 6

139

自 .net 2 以来可用的 webrequest AutomaticDecompression 属性怎么样?只需添加:

webRequest.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;

它还将 gzip,deflate 添加到接受编码标头中。

请参阅http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.automaticdecompression.aspx

于 2011-10-15T01:38:31.830 回答
4

对于 .NET Core 来说,事情要复杂一些。AGZipStream是必需的,因为AutomaticCompression. 在这里查看我的答案:https ://stackoverflow.com/a/44508724/2421277

来自答案的代码:

var req = WebRequest.CreateHttp(uri);

/*
 * Headers
 */
req.Headers[HttpRequestHeader.AcceptEncoding] = "gzip, deflate";

/*
 * Execute
 */
try
{
    using (var resp = await req.GetResponseAsync())
    {
        using (var str = resp.GetResponseStream())
        using (var gsr = new GZipStream(str, CompressionMode.Decompress))
        using (var sr = new StreamReader(gsr))

        {
            string s = await sr.ReadToEndAsync();  
        }
    }
}
catch (WebException ex)
{
    using (HttpWebResponse response = (HttpWebResponse)ex.Response)
    {
        using (StreamReader sr = new StreamReader(response.GetResponseStream()))
        {
            string respStr = sr.ReadToEnd();
            int statusCode = (int)response.StatusCode;

            string errorMsh = $"Request ({url}) failed ({statusCode}) on, with error: {respStr}";
        }
    }
}
于 2017-06-12T21:08:32.460 回答
2

我找到了一些示例代码,显示了 GZip 编码页面的整个请求/响应。它使用 GZipStream。

http://www.know24.net/blog/Decompress+GZip+Deflate+HTTP+Responses.aspx

于 2009-05-08T15:31:44.487 回答
2

您是否正在刷新和关闭流?尝试使用 Using 语句包装您的 GZipStream。

于 2009-05-08T14:58:43.550 回答
1

请参阅我上面的评论,但这通常是文件损坏的症状。如果该站点是您自己的,请替换您尝试访问的文件。

于 2009-05-08T14:54:48.507 回答
-2

本机 GZipStream 可以读取压缩的 GZIP ( RFC 1952 ) 流,但它不能处理 ZIP 文件格式。

来自http://www.geekpedia.com/tutorial190_Zipping-files-using-GZipStream.html

在 3rd 方产品上使用 GZipStream 类的缺点是它的功能有限。限制之一是您不能为放置在存档中的文件命名。当 GZipStream 将文件压缩到 ZIP 存档中时,它会从该文件中获取字节序列,并使用创建较小字节序列的压缩算法。新的字节序列被放入新的 ZIP 文件中。当您打开 ZIP 文件时,您将打开存档文件本身;最流行的 ZIP 提取器(WinZip、WinRar 等)会将 ZIP 的内容显示为与存档本身相同的文件。


编辑:上面的注释是不正确的。GZipStream 不生成 ZIP 文件。它不是“单文件 ZIP 流”。它是一个 GZIP 流。它们是不同的东西。无法保证处理 ZIP 档案的工具能够处理 .gz 文件。


对于可以读取 ZIP 存档的实现,而不是单文件 ZIP 流,请尝试#ziplib (SharpZipLib, 以前称为 NZipLib)

于 2009-05-08T14:00:07.607 回答