Общая длина файла GZIP в C#

У меня есть заархивированный файл размером в несколько ГБ, я хочу получить размер разархивированного содержимого, но не хочу распаковывать файл на С#. Какую библиотеку я могу использовать? Когда я щелкаю правой кнопкой мыши файл .gz и захожу в «Свойства», затем на вкладке Archive появляется имя свойства TotalLength, которое показывает это значение. Но я хочу получить его программно, используя С#. Любая идея?


person Muhammad Ummar    schedule 12.01.2011    source источник
comment
Информация может присутствовать в заголовке gzip. Но я не могу помочь больше, чем это.   -  person leppie    schedule 12.01.2011


Ответы (3)


Последние 4 байта файла gz содержат длину.

Так что это должно быть что-то вроде:

using(var fs = File.OpenRead(path))
{
  fs.Position = fs.Length - 4;
  var b = new byte[4];
  fs.Read(b, 0, 4);
  uint length = BitConverter.ToUInt32(b, 0);
  Console.WriteLine(length);
}
person leppie    schedule 12.01.2011
comment
ах, намного лучше; Я не уверен, как это обрабатывается, когда › 4 ГБ - person Marc Gravell; 12.01.2011
comment
Спасибо, Леппи... на самом деле в моем случае файл будет меньше 4 Гб... Спасибо за помощь... - person Muhammad Ummar; 12.01.2011
comment
@leppie без проблем, спасибо вам за отличный ответ. - person johnnyRose; 08.08.2016

Последние байты файла .gz представляют собой несжатый входной размер по модулю 2^32. Если размер вашего несжатого файла не превышает 4 ГБ, просто прочитайте последние 4 байта файла. Если у вас есть файл большего размера, я не уверен, что его можно получить без распаковки потока.

person Gabe    schedule 12.01.2011

РЕДАКТИРОВАТЬ: см. ответы Леппи и Гейба; единственная причина, по которой я сохраняю это (а не удаляю), заключается в том, что это может быть необходимо, если вы подозреваете, что длина > 4 ГБ


Для gzip эти данные, похоже, недоступны напрямую — я просмотрел GZipStream и SharpZipLib эквивалентно - ни то, ни другое не работает. Лучшее, что я могу предложить, это запустить его локально:

    long length = 0;
    using(var fs = File.OpenRead(path))
    using (var gzip = new GZipStream(fs, CompressionMode.Decompress)) {
        var buffer = new byte[10240];
        int count;
        while ((count = gzip.Read(buffer, 0, buffer.Length)) > 0) {
            length += count;
        }
    }

Если это был zip, то SharpZipLib:

    long size = 0;
    using(var zip = new ZipFile(path)) {
        foreach (ZipEntry entry in zip) {
            size += entry.Size;
        }
    }
person Marc Gravell    schedule 12.01.2011
comment
Спасибо, Марк, первый метод сработал для меня... но вычисление несжатого файла размером 2 ГБ занимает слишком много времени... и это должно быть так, как мы считаем в цикле... Нет ли какого-нибудь быстрого способа? - person Muhammad Ummar; 12.01.2011
comment
@Ummar: И Гейб, и я объяснили «правильный» способ сделать это. Вышеуказанный способ будет работать, но представьте, что вы используете его для 1000 файлов размером 2 ГБ, это займет вечность. - person leppie; 12.01.2011
comment
@Ummar - см. ответ @leppie - person Marc Gravell; 12.01.2011