2009-12-27 16 views
6

Nach der Spezifizierung von gz die Dateigröße wird in den letzten 4bytes einer .gz-Datei gespeichert.erhalten Sie die Dateigröße von sehr großen .gz-Datei auf einer 64bit-Plattform

I 2 Dateien mit

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

erstellt haben gziped ich sie

gzip 500M 5G 

ich die letzten 4 Bytes

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

Es scheint, dass schlagen die unsichtbare 32bit Barriere tun geprüft, macht den in die ISIZE geschriebenen Wert komplett unsinnig. Was ärgerlicher ist, als wenn sie stattdessen ein Fehlerbit verwendet hätten.

Kennt jemand eine Möglichkeit, die unkomprimierte .gz-Dateigröße aus der .gz-Datei zu erhalten, ohne sie zu extrahieren?

dank

Spezifikation: http://www.gzip.org/zlib/rfc-gzip.html

edit: wenn jemand es aus, um zu versuchen, könnten Sie mit diesem anstelle von/dev/urandom

+0

'dd suchen = 10G if =/dev/zero of = = out.dat zu zählen 0 'ist praktisch für die meisten Dateisysteme – nodakai

Antwort

8

warten ist es nicht ein.

Die einzige Möglichkeit, die genaue Größe eines komprimierten Streams zu erhalten, besteht darin, sie tatsächlich zu dekomprimieren (selbst wenn Sie alles nach/dev/null schreiben und nur die Bytes zählen).

Seine erwähnenswert, dass ISIZE definiert als

ISIZE (Input SIZE)
Diese enthält die Größe der ursprünglichen (nicht komprimierten) -Eingang
Daten Modulo 2^32.

im gzip RFC so ist es nicht tatsächlich an der 32-Bit-Barriere zu brechen, was Sie sehen, erwartetes Verhalten ist.

2

ich nicht versucht,/dev/null haben eine Datei von der Größe Sie erwähnt, aber ich mit

zcat file.gz | wc -c 
die unkomprimierte Größe einer gz-Datei oft finden

wenn ich die unkomprimierte Datei nicht herumliegen lassen möchte oder sie erneut komprimieren möchte.

Offensichtlich sind die Daten unkomprimiert, werden dann aber an wc weitergeleitet.

Es ist jedenfalls einen Versuch wert.

EDIT: Als ich versuchte, eine 5G-Datei mit Daten von/dev Erstellen/random es eine Datei 5G der Größe 5120000000 produziert, obwohl mein Datei-Manager dies als 4,8 g

berichtete

Dann komprimierte ich es mit gzip 5G , die Ergebnisse 5G.gz hatten die gleiche Größe (nicht viel Kompression von zufällige Daten).

Dann zcat 5G.gz | wc -c gemeldet die gleiche Größe wie die ursprüngliche Datei: 5120000000 Bytes. Also schien mein Vorschlag für diesen Prozess überhaupt funktioniert zu haben.

Vielen Dank für

+0

Ja danke, aber meine Frage war mehr im Sinne von. Wie bekomme ich die unkomprimierte Dateigröße, ohne tatsächlich eine Dekomprimierung durchzuführen. Für Dateien kleiner als 32-Bit-Dateien. Sie können nur die letzten 4 Bytes extrahieren. Dies ist bei größeren Dateien nicht möglich, und wie Sie es getan haben, ist die einzige Möglichkeit, eine Dekomprimierung durchzuführen. – monkeyking

+0

Aber meine Methode führte eine Dekomprimierung durch, die die ursprüngliche komprimierte Datei nicht beeinflusste und keine extra unkomprimierte Datei erstellt. Es würde keine Reinigung danach geben. Und ich denke, es ist erwähnenswert, dass die Antwort, die Sie angenommen haben, besagt, dass die Dekomprimierung der einzige Weg ist, die genaue Größe zu erhalten. Es macht Sinn, dass * der einzige Weg, um herauszufinden, was in der Box ist, ist es zu öffnen *. – pavium

+0

Ja, es hat die ursprüngliche Datei nicht beeinflusst, aber mein Anliegen war nicht "nicht berühren" die Datei, sondern nur eine Geschwindigkeitsproblem. Wenn ich ein Array für die gesamten Daten zuordnen möchte, dann sollte ich die Größe kennen. Dies erfordert eine Dekomprimierung, gefolgt von einer weiteren Dekomprimierung für die eigentliche Datenkopie. Dies ist nicht notwendig, wenn die Datei kleiner als 2.1 Gig ist. std gunzip kann auch auf stdout dekomprimieren, gunzip -c Datei tun | wc -c Aber vielen Dank für Ihre Eingabe :) – monkeyking

0

gzip hat eine Option -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. 
+0

Diese Lösung funktioniert nur für eine Disk-Datei, nicht für einen Stream (die ursprüngliche Frage hat keinen Stream angegeben, ist also in dieser Hinsicht eine brauchbare Antwort). Leider wird für Dateigrößen größer als 2^32-1 Bytes die unkomprimierte Größe modulo 2^32 angezeigt und ist daher unzuverlässig. – Curt