получить размер очень большого файла .gz на 64-битной платформе

В соответствии со спецификацией gz размер файла сохраняется в последних 4 байтах файла .gz.

Я создал 2 файла с

dd if=/dev/urandom of=500M bs=1024 count=500000
dd if=/dev/urandom of=5G bs=1024 count=5000000

я их заархивировал

gzip 500M 5G

Я проверил последние 4 байта, делая

tail -c4 500M|od -I      (returns 512000000 as expected)
tail -c4 5G|od -I        (returns 825032704 as not expected)

Кажется, что преодоление невидимого 32-битного барьера делает значение, записанное в ISIZE, совершенно бессмысленным. Что более раздражает, чем если бы вместо этого они использовали какой-то бит ошибки.

Кто-нибудь знает способ получить несжатый файл .gz из .gz без его извлечения?

Спасибо

спецификация: http://www.gzip.org/zlib/rfc-gzip.html

редактировать: если кто-то попробует, вы можете использовать /dev/zero вместо /dev/urandom


person monkeyking    schedule 27.12.2009    source источник
comment
dd seek=10G if=/dev/zero of=out.dat count=0 удобнее для большинства файловых систем   -  person nodakai    schedule 11.08.2015


Ответы (3)


Нет ни одного.

Единственный способ получить точный размер сжатого потока — это пойти и распаковать его (даже если вы записываете все в /dev/null и просто считаете байты).

Стоит отметить, что ISIZE определяется как

ISIZE (Входной размер)
Содержит размер исходных (несжатых) входных
данных по модулю 2^32.

в gzip RFC, поэтому на самом деле он не нарушает 32-битный барьер, то, что вы видите, является ожидаемым поведением.

person Kevin Montrose    schedule 27.12.2009

Я не пробовал это с файлом указанного вами размера, но я часто нахожу несжатый размер файла .gz с

zcat file.gz | wc -c

когда я не хочу оставлять несжатый файл без присмотра или сжимать его снова.

Очевидно, что данные не сжаты, но затем передаются в wc.

В любом случае стоит попробовать.

EDIT: когда я попытался создать файл 5G с данными из /dev/random, он создал файл 5G размером 5120000000, хотя мой файловый менеджер сообщил, что это 4,8G.

Затем я сжал его с помощью gzip 5G, результаты 5G.gz были того же размера (не сильное сжатие случайных данных).

Затем zcat 5G.gz | wc -c сообщил о том же размере, что и исходный файл: 5120000000 байт. Так что мое предложение, похоже, сработало для этого испытания.

Спасибо за ожидание

person pavium    schedule 27.12.2009
comment
Да спасибо, но мой вопрос был больше в смысле. Как получить несжатый размер файла без фактической распаковки. Для файлов меньше 32-битных файлов. Вы можете просто извлечь последние 4 байта. Это невозможно для больших файлов, и, как вы уже сделали, единственный способ — выполнить распаковку. - person monkeyking; 28.12.2009
comment
Но мой метод выполнил декомпрессию, которая не повлияла на исходный сжатый файл и не создала дополнительный несжатый файл. Никакой уборки потом не будет. И я думаю, стоит отметить, что ответ, который вы приняли, сказал, что распаковка была единственным способом получить точный размер. Логично, что единственный способ узнать, что в коробке, это открыть ее. - person pavium; 28.12.2009
comment
Да, это не повлияло на исходный файл, но меня беспокоило не прикосновение к файлу, а просто проблема со скоростью. Если я хочу выделить массив для всех данных, то я должен знать размер. Это требует выполнения декомпрессии, за которой следует еще одна декомпрессия фактической копии данных. В этом нет необходимости, если файл меньше 2,1 гига. std gunzip также можно распаковать в стандартный вывод, выполнив команду gunzip -c file |wc -c Но спасибо за ваш вклад :) - person monkeyking; 28.12.2009
comment
все комментарии в сторону: если ничего не помогает практическое решение. - person Pat; 18.10.2013

gzip имеет опцию -l:

       -l --list
          For each compressed file, list the following fields:

              compressed size: size of the compressed file
              uncompressed size: size of the uncompressed file
              ratio: compression ratio (0.0% if unknown)
              uncompressed_name: name of the uncompressed file

          The uncompressed size is given as -1 for files not in gzip format, such as compressed .Z files. To
          get the uncompressed size for such a file, you can use:

              zcat file.Z | wc -c

          In combination with the --verbose option, the following fields are also displayed:

              method: compression method
              crc: the 32-bit CRC of the uncompressed data
              date & time: time stamp for the uncompressed file

          The compression methods currently supported are deflate, compress, lzh (SCO compress -H) and pack.
          The crc is given as ffffffff for a file not in gzip format.

          With --name, the uncompressed name,  date and time  are those stored within the compress  file  if
          present.

          With --verbose, the size totals and compression ratio for all files is also displayed, unless some
          sizes are unknown. With --quiet, the title and totals lines are not displayed.
person Pat    schedule 17.10.2013
comment
Это решение работает только для файла на диске, а не для потока (исходный вопрос не указывал поток, поэтому в этом отношении это жизнеспособный ответ). К сожалению, для файлов размером более 2^32-1 байт несжатый размер отображается по модулю 2^32, что ненадежно. - person Curt; 06.02.2016