61

Gzip圧縮を使用してページをリクエストすると、次のエラーが多数発生します。

System.IO.InvalidDataException:GZipフッターのCRCが、解凍されたデータから計算されたCRCと一致しません

私はネイティブGZipStreamを使用して解凍し、これに対処することを検討しています。それを念頭に置いて、この問題を適切に処理するこのまたは別のGZipライブラリ(無料?)に対処するための回避策はありますか?

webResponseContentEncodingが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;

また、accept エンコーディング ヘッダーに 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

ストリームをフラッシュして閉じていますか? GZipStream を Using ステートメントでラップしてみてください。

于 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から:

サードパーティ製品よりも GZipStream クラスを使用することの欠点は、機能が制限されていることです。制限の 1 つは、アーカイブに配置するファイルに名前を付けることができないことです。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 に答える