compression – La forma más rápida de calcular el tamaño sin comprimir de un archivo GZIPPED grande

Pregunta:

Una vez que un archivo está comprimido con gzip, ¿hay alguna manera de consultarlo rápidamente para decir cuál es el tamaño del archivo sin comprimir (sin descomprimirlo), especialmente en los casos en que el archivo sin comprimir tiene un tamaño> 4 GB?

De acuerdo con el RFC https://www.rfc-editor.org/rfc/rfc1952#page-5 , puede consultar los últimos 4 bytes del archivo, pero si el archivo sin comprimir era> 4GB, entonces el valor solo representa el uncompressed value modulo 2^32

Este valor también se puede recuperar ejecutando gunzip -l foo.gz , sin embargo, la columna "descomprimida" solo contiene el uncompressed value modulo 2^32 nuevamente, presumiblemente mientras lee el pie de página como se describe arriba.

Me preguntaba si hay alguna manera de obtener el tamaño del archivo sin comprimir sin tener que descomprimirlo primero, esto sería especialmente útil en el caso de que los archivos comprimidos con gzip contengan más de 50 GB de datos y tomaría un tiempo descomprimirlos usando métodos como gzcat foo.gz | wc -c


EDITAR: La limitación de 4GB se reconoce abiertamente en la página de man de la utilidad gzip incluida con OSX ( Apple gzip 242 )

  BUGS
    According to RFC 1952, the recorded file size is stored in a 32-bit
    integer, therefore, it can not represent files larger than 4GB. This
    limitation also applies to -l option of gzip utility.

Respuesta:

Creo que la forma más rápida es modificar gzip para que las pruebas en modo detallado generen el número de bytes descomprimidos; en mi sistema, con un archivo de 7761108684 bytes, obtengo

% time gzip -tv test.gz
test.gz:     OK (7761108684 bytes)
gzip -tv test.gz  44.19s user 0.79s system 100% cpu 44.919 total

% time zcat test.gz| wc -c
7761108684
zcat test.gz  45.51s user 1.54s system 100% cpu 46.987 total
wc -c  0.09s user 1.46s system 3% cpu 46.987 total

Para modificar gzip (1.6, disponible en Debian), el parche es el siguiente:

--- a/gzip.c
+++ b/gzip.c
@@ -61,6 +61,7 @@
 #include <stdbool.h>
 #include <sys/stat.h>
 #include <errno.h>
+#include <inttypes.h>
 
 #include "closein.h"
 #include "tailor.h"
@@ -694,7 +695,7 @@
 
     if (verbose) {
         if (test) {
-            fprintf(stderr, " OK\n");
+            fprintf(stderr, " OK (%jd bytes)\n", (intmax_t) bytes_out);
 
         } else if (!decompress) {
             display_ratio(bytes_in-(bytes_out-header_bytes), bytes_in, stderr);
@@ -901,7 +902,7 @@
     /* Display statistics */
     if(verbose) {
         if (test) {
-            fprintf(stderr, " OK");
+            fprintf(stderr, " OK (%jd bytes)", (intmax_t) bytes_out);
         } else if (decompress) {
             display_ratio(bytes_out-(bytes_in-header_bytes), bytes_out,stderr);
         } else {

Se implementó un enfoque similar en gzip , y se incluirá en la versión siguiente a 1.11; gzip -l ahora descomprime los datos para determinar su tamaño.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top

web tasarım