2016-08-30 11 views
1

私は* .gzをファイル解凍方法があります:それは完全に働いたが、最近、私は間違ったサイズのファイルのパックを受け解凍ファイル

using (FileStream originalFileStream = new FileStream(gztempfilename, FileMode.Open, FileAccess.Read)) 
{ 
    using (FileStream decompressedFileStream = new FileStream(outputtempfilename, FileMode.Create, FileAccess.Write)) 
    { 
    using (GZipStream decompressionStream = new GZipStream(originalFileStream, CompressionMode.Decompress)) 
    { 
     decompressionStream.CopyTo(decompressedFileStream); 
    } 
    } 
} 

を: 私は7-ZIPでそれらを開いたときに彼らはパックされたサイズ〜1,600,000とサイズ = 7(それは~20,000,000であるはずです)があります。 enter image description here 私はこのコードを使用してそれらを抽出するので、私はファイルの一部だけを取得します。しかし、私が7-zipを使ってこのファイルを解凍すると、完全なファイルが得られます。

私のコードでこのような状況をどうやって処理できますか?

+0

私はここで間違ったサイズを取得していません。 GZipのアーカイブは予想よりも小さくなっていますか? GZip形式では元のファイルサイズはそのままではなく、[_2^32_でモジューロ除算した結果](http://www.zlib.org/rfc-gzip.html)に注意してください。 –

+0

スクリーンショットを追加して明確にしました。 – Ivan

+1

ライトブルーの「テスト」ボタンを押したときの表示は何ですか? –

答えて

2

私の推測では、ファイルをGZippingときにはもう一方の端は間違いをするということです。 ISIZE bytesが正しく設定されていないようです。

ISIZEバイトは、有効なGZipファイルの最後の4バイトであり、圧縮データバイトの直後に32ビットのCRC値が続きます。

7-Zipはこのような間違いに対して堅牢であると思われますが、GZipStreamはそうではありません。しかし、7-Zipがあなたにエラーを表示していないことは奇妙です。それは場合にはサイズが単に間違っている場合には、

  • 「データの予期しない終了」...(7-ZIP 16.02のx64/Win7のでテスト)の一部または全てを

    • CRCエラーをお見せなければなりませんISIZEバイトが切り捨てられます。
    • ISIZEバイトの後にさらにデータがある場合は、「ペイロードデータの最後のデータがあります。

    7-Zipは、ファイルが有効かどうか、読み込まれたバイトが実際にISIZEバイトであるかどうかをチェックせずに、パックされたファイルの最後の4バイトを常に使用します。

    これを確認するには、GZipファイルの最後の4バイトを16進数で確認します。あなたの例では、正確には07 00 00 00でなければなりません。

    解凍した元のファイルの正確なサイズを知っていれば、それらのバイトを置き換えて正しいサイズを指定することができます。例えば、解凍されたファイルのサイズは、(8桁へ -padded)ヘクスで01312D4Eある、これらのバイトは4E 2D 31 01であるべきである場合。

    正確なサイズがわからない場合は、最大値(つまりFF FF FF FF)で置き換えることができます。

    その後、解凍コードをもう一度お試しください。

    これは明らかにあなたの問題に対する唯一の解決策です。あなたが受け取ったファイルをGZipsするコードを修正するか、GZipStreamよりも堅牢なライブラリを探してみてください。

  • +1

    07 00 00 00 FF FF FF FFに置き換えようとしましたが、7zipファイルマネージャのサイズは4,294,967,295のように表示されました。しかし、私は私のコードを使用してこのファイルを解凍しようとすると、私はまだ同じ問題を抱えています。また、私がこの最後のバイトを変更したとき、私が7-zipを使用して解凍しようとしていたときに "CRCに失敗しました"というエラーが出ました。今度はSevenZipExtractorライブラリを使用します。 – Ivan

    +0

    @Ivanので、あなたのコードが 'InvalidDataException'を投げることはありませんか? ISIZEバイトを変更した後でも?アンパックコードの周りに 'try-catch'ブロックを追加しようとしましたか? –

    +0

    はい、例外をスローしません。私はこのアーカイブに大きなxmlファイルを持っており、最初の2つのタグだけを解凍します。 – Ivan

    0

    サイズを確認するためにこれを試しましたか?すなわち:

    byte[] bArray; 
    using (FileStream f = new FileStream(tempFile, FileMode.Open)) 
    { 
        bArray= new byte[f.Length]; 
        f.Read(b, 0, f.Length); 
    } 
    

    よろしく

    試してみてください。

      GZipStream uncompressed = new GZipStream(streamIn, CompressionMode.Decompress, true); 
          FileStream streamOut = new FileStream(tempDoc[0], FileMode.Create, FileAccess.Write, FileShare.None); 
    
    +0

    "decompressionStream.CopyTo(decompressedFileStream);"にブレークポイントを設定しました。すべてのストリームのラインとチェクシングされた長さ。 originalFileStream:1554925; decompressedFileStream:165それはGZipStreamのどこかで失われたようです。 – Ivan

    +0

    私は同じことをするプロセスを持っています、唯一の違いはgzipstreamと出力ファイルストリームの最終値です。それがあなたのために働く場合に試してください。 –

    +0

    私は試しましたが、助けにならなかった – Ivan

    1

    System.IO.Compression.GZipStreamの代わりにthisライブラリのICSharpCode.SharpZipLib.GZip.GZipInputStreamを使用しました。

    関連する問題