3

組み込みの .net 4.0 Gzip および Deflate クラスを使用して、プログラムで 3GB (7GB 非圧縮) の gzip ファイルを解凍するのに問題があります。

私の理解では、どちらも 4GB を超えるファイルをサポートする必要がありますが、機能していないようです。問題のファイルを WinRAR で手動で解凍し、基になる csv ファイルをストリーム リーダーでストリーミングし、行数をカウントすると、約 7500 万行という期待される結果が得られます。ただし、GzipStream または DeflateStream を使用してこれを行うと、ストリーム リーダーは途中で停止し (4GB マーク付近)、「ストリームの終わり」を報告し、エラーなしで終了します。これらのリーダーを使用すると、ストリームが終了するまでに約 3,400 万行に到達するだけです。

次に、.net zip http://dotnetzip.codeplex.com/の最新のバイナリを試してみました が、途中でエラーが発生しました。「宛先配列の長さが不十分です。destIndex と長さ、および配列の下限を確認してください。」

私はこのファイルを作成しませんでしたが、同じソースからの小さなファイルで問題が発生したことはありません。そのため、サイズに関する何かが問題の原因であると思われます。このファイルの作成に使用されたツールが 64 ビットに準拠していない可能性がありますが、作成者にバグを報告する前に、バグが gzip 抽出ロジックで私たちの側にないことを確認したいと思います。

どんな考えでも大歓迎です。以下の抽出コードとテスト方法の例:

var msGZ = 0;//gives 34million
var fileName = @"C:\MyFile.csv.gz";
using (System.IO.Stream input = System.IO.File.OpenRead(filename))
using (var gz = new GZipStream(stream, CompressionMode.Decompress))
using (var r = new StreamReader(gz))
{
    while (!r.EndOfStream)
    {
        r.ReadLine();
        msGZ++;
    }
}



var msDF = 0;  //gives 34million
using (System.IO.Stream input = System.IO.File.OpenRead(filename))
using (var df = new DeflateStream(stream, CompressionMode.Decompress))
using (var r = new StreamReader(df))
{
    while (!r.EndOfStream)
    {
        r.ReadLine();
        msDF++;
    }
}



var csvCount = 0;//roughly 75million lines

using (var ms = System.IO.File.OpenRead("UncompressedBYWinRAR.csv"))
{
    var r = new StreamReader(ms);
    while (!r.EndOfStream)
    {
        r.ReadLine();
        csvCount++;
    }
}




var zipNet = 0;

//Zip.Net throws this error half way through at around line 34million
//"Destination array was not long enough. Check destIndex and length, and the array's lower bounds."

using (System.IO.Stream input = System.IO.File.OpenRead(filename))
using (Stream decompressor = new Ionic.Zlib.GZipStream(input, Ionic.Zlib.CompressionMode.Decompress, true))
using (var r = new StreamReader(decompressor))
{
    while (!r.EndOfStream)
    {
        r.ReadLine();
        zipNet++;
    }
}
4

1 に答える 1

0

Io.GZipStreamの代わりに SharpZip の GZipInputStream を使用すると、解決策が得られました。

于 2017-12-29T00:15:23.603 に答える