Cara tercepat untuk mengetahui ukuran file GZIPPED besar yang tidak terkompresi

24

Setelah file di-gzip, apakah ada cara untuk dengan cepat menanyakannya untuk mengatakan apa ukuran file yang tidak dikompresi (tanpa mendekompresinya), terutama dalam kasus di mana file yang tidak dikompresi berukuran> 4GB.

Menurut RFC https://tools.ietf.org/html/rfc1952#page-5 Anda dapat meminta 4 byte terakhir file, tetapi jika file yang tidak dikompresi adalah> 4GB maka nilainya hanya mewakiliuncompressed value modulo 2^32

Nilai ini juga dapat diambil dengan menjalankan gunzip -l foo.gz, namun kolom "tidak terkompresi" hanya berisi uncompressed value modulo 2^32lagi, mungkin karena sedang membaca catatan kaki seperti dijelaskan di atas.

Saya hanya bertanya-tanya apakah ada cara untuk mendapatkan ukuran file yang tidak terkompresi tanpa harus mendekompresnya terlebih dahulu, ini akan sangat berguna dalam kasus di mana file gzip berisi 50GB + data dan akan membutuhkan waktu untuk mendekompresi menggunakan metode seperti gzcat foo.gz | wc -c


EDIT: Batasan 4GB secara terbuka diakui di manhalaman gziputilitas yang disertakan dengan 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.
djhworld
sumber
2
+1 pertanyaan bagus! Saya menduga jawabannya tidak, format tajuk itu dirancang dalam waktu sebelum ukuran file seperti itu diantisipasi. Berpikir tentang itu, gzipharus lebih tua dari banyak pengguna di komunitas ini!
Celada
2
gzipkeluar pada tahun 1992. Saya akan terkejut jika ada banyak anak berusia 23 tahun berkeliaran di sekitar sini. Saya yakin ada beberapa tetapi dari apa yang saya tahu usia rata-rata adalah sekitar 30-35.
Bratchley
2
Mungkin saat yang tepat untuk beralih ke xzyang tidak memiliki batasan itu. GNU beralih ke xz.
Stéphane Chazelas
@ StéphaneChazelas Menarik. Sayangnya file yang saya minati berada di luar kendali saya (yaitu kami menerima mereka terkompresi), tetapi sepertinya xz akan 'menyelesaikan` masalah ini.
djhworld

Jawaban:

11

Saya percaya cara tercepat adalah memodifikasi gzipsehingga pengujian dalam mode verbose menghasilkan jumlah byte yang didekompresi; pada sistem saya, dengan file 7761108684-byte, saya dapatkan

% 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

Untuk memodifikasi gzip (1.6, seperti yang tersedia di Debian), tambalannya adalah sebagai berikut:

--- 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 {
Stephen Kitt
sumber
Apakah masih membangun data aktual secara internal, atau -tsudah dioptimalkan dalam hal itu? Peningkatannya cukup kecil untuk membuatnya terlihat seperti Anda hanya menghemat waktu keluaran.
frostschutz
Ya, itu perlu mendekompresi segalanya untuk mengetahui ukuran aslinya ... Jadi ini hanya menghemat waktu keluaran, tapi saya pikir hanya itu yang bisa diselamatkan.
Stephen Kitt
Menarik, ya saya berpikir Anda perlu mengubah kode untuk benar-benar menyelesaikannya. Sayangnya, dalam contoh saya, file yang saya minati sebenarnya tidak dalam kendali saya, saya menerimanya dari pihak luar sehingga tidak dapat mengompresnya. Saya pikir satu-satunya cara untuk mendukung penuh> file 4GB adalah menambal gzip untuk memiliki footer 12 byte, 4 byte untuk CRC dan 8 byte (64 bit) untuk filesize. Namun ini akan merusak kompatibilitas dengan gzip yang ada!
djhworld
Solusi yang saya berikan di atas tidak melibatkan mengompresi file pada awalnya, meskipun saya sedang menjalankan gzip; Saya hanya menjalankan gzipfile terkompresi, yang tidak mengkompres ulang mereka, itu hanya memverifikasi mereka. (Patch adalah pembuktian konsep cepat dan kotor, perlu beberapa perubahan lagi untuk dikerjakan gunzip.)
Stephen Kitt
@StephenKitt Ah menarik! Retas yang lebih baik / kotor akan menyematkan data itu di FCOMMENTlapangan. Dengan cara itu pengguna dapat meminta rentang byte untuk mengambil data itu. Ini akan berguna dalam kasus saya, terutama untuk barang-barang yang disimpan di Amazon S3
djhworld
0

Jika Anda membutuhkan ukuran file terkompresi atau set file, Anda terbaik adalah dengan penggunaan tar -zatau tar -jbukan gzipsebagai tarmeliputi terkompresi ukuran file. Gunakan lesspipeuntuk mengintip daftar file:

aptitude install lesspipe
lesspipe <compressed file> | less

Jika lessdikonfigurasi untuk digunakan lesspipe:

less <compressed file>

Hanya perlu diingat bahwa ini bisa memakan waktu yang sangat lama. Namun sistem Anda tetap responsif, yang memungkinkan Anda untuk membunuh proses dekompresi.

Pendekatan lain adalah dengan mencatat rasio terkompresi dan meminta file [teks] itu sebagai gantinya:

gzip --verbose file 2>&1 | tee file.gz.log
file:    64.5% -- replaced with file.gz

Ini membutuhkan perhitungan untuk menemukan ukuran file sebenarnya.

Anda juga bisa melakukan hal yang sama tar, yang sebenarnya saya lakukan dengan backup berukuran besar karena mencegah menjalankan seluruh proses dekompresi untuk hanya mendapatkan ukuran atau nama file, misalnya.


sumber
2
Tidak tar.gz harus didekompresi sepenuhnya juga untuk mendapatkan daftar semua file?
frostschutz
Memang harus demikian. Ini adalah satu-satunya cara saya bisa memikirkan untuk mendapatkan ukuran file yang tidak terkompresi. Dengan tarAnda memiliki ukuran file asli dicatat dalam arsip. Saya tidak yakin zipberperilaku berbeda, di sisi lain.
1
Pada titik itu OP mungkin juga melakukan wc -cperintah.
Bratchley
@Bratchley tentu saja. Tetapi akan membutuhkan banyak waktu untuk mendapatkan semua hasil. Oleh karena itu dua saran saya untuk mencatat ukuran file.
0

Bagaimana dengan

gzip -l file.gz|tail -n1|awk '{print $2}'

numfmt --to=iec $(gzip -l file.gz|tail -n1|awk '{print $2}')
Syco
sumber
1
Itu tidak berfungsi untuk file besar, seperti yang dijelaskan oleh OP.
Stephen Kitt
-2
gunzip -c $file | wc -c

Ini akan memakan waktu lama, tetapi akan memberi Anda ukuran final dalam byte.

Nick
sumber
5
Inilah tepatnya yang ingin dihindari oleh OP.
depquid