GzipStream (.net 4.0) 4 ГБ проблема - PullRequest
       72

GzipStream (.net 4.0) 4 ГБ проблема

3 голосов
/ 01 апреля 2011

У меня возникают проблемы с программным распаковыванием gzip-файла объемом 3 ГБ (без сжатия), используя встроенные GZIP-файлы .net 4.0 и классы Deflate.

Насколько я понимаю, они оба должны поддерживать файлы размером более 4 ГБ, но, похоже, они не работают. Когда я вручную разархивирую рассматриваемый файл с помощью WinRAR, а затем выполняю потоковую передачу через базовый файл csv с помощью средства чтения потоков и подсчета строк, я получаю ожидаемый результат, около 75 миллионов строк. Однако при этом с помощью GzipStream или DeflateStream программа чтения потоков останавливается чуть более чем на половине пути (около отметки 4 ГБ) и сообщает об окончании потока и завершается без ошибок. Используя эти читатели, я получаю около 34 миллионов строк до окончания потока.

Затем я попробовал последний бинарный файл .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++;
    }
}

1 Ответ

0 голосов
/ 29 декабря 2017

Использование GZipInputStream из SharpZip вместо Io.GZipStream предоставило решение.

...