Büyük GZIPPED dosyasının sıkıştırılmamış boyutunda çalışmanın en hızlı yolu


24

Bir dosya gziplendikten sonra, özellikle sıkıştırılmamış dosyanın> 4GB boyutunda olduğu durumlarda, sıkıştırılmamış dosya boyutunun ne olduğunu (açmadan) söylemek için hızlı bir şekilde sorgulamanın bir yolu vardır.

RFC https://tools.ietf.org/html/rfc1952#page-5’e göre , dosyanın son 4 baytını sorgulayabilirsiniz, ancak sıkıştırılmamış dosya> 4GB ise, bu değer sadece değeri temsil eder.uncompressed value modulo 2^32

Bu değer, çalıştırılarak da elde edilebilir gunzip -l foo.gz, ancak "sıkıştırılmamış" sütun uncompressed value modulo 2^32, muhtemelen yukarıda açıklandığı gibi altbilgiyi okuduğu gibi , tekrar içerir .

Sadece sıkıştırılmamış dosya boyutunu, önce sıkıştırmasını açmaya gerek kalmadan elde etmenin bir yolu olup olmadığını merak ediyordum, bu özellikle, gzipli dosyaların 50GB + veri içerdiği ve bu gibi yöntemleri kullanarak sıkıştırmanın açılması için özellikle yararlı olacaktı. gzcat foo.gz | wc -c


EDIT: 4GB sınırlaması, OSX ( ) programındaki yardımcı program mansayfasında açıkça kabul edildi.gzipApple 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.

2
+1 iyi soru! Cevabın hayır olduğundan şüpheleniyorum, bu başlık formatı bu tür dosya boyutları beklenmeden bir zaman önce tasarlandı. Bir düşünün gzip, bu topluluktaki birçok kullanıcıdan daha büyük olmalı!
Celada

2
gzip1992'de ortaya çıktı. Etrafta dolanan 23 yaşındaki birileri olsaydı şaşırırdım. Bazıları olduğuna eminim ama ortanca yaşın 30-35 civarında olduğunu söyleyebilirim.
Bratchley

2
Geçiş yapmak için iyi bir zaman xzolabilir; GNU geçiş yapıyor xz.
Stéphane Chazelas

@ StéphaneChazelas İlginç. Maalesef ilgilendiğim dosyalar benim kontrolüm dışında (yani sıkıştırılmış olarak alıyoruz), fakat kesinlikle xz bu sorunu çözecek gibi görünüyor .
djhworld

Yanıtlar:


11

En hızlı yolun, gzipayrıntılı modda yapılan testin, sıkıştırılmış bayt sayısını vermesi için değiştirmenin olduğuna inanıyorum ; sistemimde bir 7761108684 bayt dosyayla alıyorum

% 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

Gzip'i değiştirmek için (1.6, Debian'da olduğu gibi), yama aşağıdaki gibidir:

--- 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 {

Hala asıl verileri dahili olarak oluşturuyor mu, yoksa -tbu konuda zaten optimize edilmiş mi? Geliştirme, yalnızca çıktı zamanını kurtarmış gibi görünmesini sağlayacak kadar küçüktür.
frostschutz

Evet, orjinal boyutunu bulmak için herşeyi açmak gerekiyor ... Yani bu sadece çıktı zamanından tasarruf ediyor, ama sanırım kurtarabilecek tek şey bu.
Stephen Kitt

İlginç, evet, bunun işe yaraması için kodu değiştirmeniz gerekeceğini düşünüyordum. Maalesef benim ilgilendiğim dosyalar aslında benim kontrolümde değil, onları harici bir partiden alıyorum, bu yüzden ilk etapta onları sıkıştıramadım. > 4GB'lık dosyaları tam olarak desteklemenin tek yolu gzip'in 12 baytlık altbilgi, CRC için 4 bayt ve dosya boyutu için 8 bayt (64 bit) olacak şekilde düzeltilmesi olduğunu düşünüyorum. Ancak bu, mevcut gziplerle geriye doğru uyumluluğu bozabilir!
djhworld

Yukarıda verdiğim çözüm, çalıştırdığım halde dosyaları başlangıçta sıkıştırmayı içermiyor gzip; Sadece koşmak gziponları yeniden sıkıştırmak değil sıkıştırılmış dosyalar üzerinde, sadece onları doğrular. (Yama hızlı ve kirli bir kavramdır, çalışması için birkaç değişiklik daha gerekir gunzip.)
Stephen Kitt

@StephenKitt Ah ilginç! Daha iyi / daha kirli bir kesmek, bu verileri FCOMMENTalana gömmek olacaktır . Bu şekilde kullanıcılar bu verileri almak için bir bayt aralığı sorgulayabilirler. Bu benim durumumda, özellikle Amazon S3
djhworld

0

Eğer dosyaların bir sıkıştırılmış dosya veya kümesinin boyutunu gerekiyorsa, en iyi bahis kullanımına olan tar -zveya tar -jyerine gzipkadar tarsıkıştırılmamış dosya boyutunu içerir. lesspipeDosya listesine bakmak için kullanın :

aptitude install lesspipe
lesspipe <compressed file> | less

Kullanmak lessiçin yapılandırılmışsa lesspipe:

less <compressed file>

Sadece aklınızda bulundurun, ancak çok uzun zaman alabilir. Ancak sisteminiz yanıt vermeye devam ediyor, bu da dekompresyon işlemini öldürmenize izin veriyor.

Başka bir yaklaşım, sıkıştırılmış oranı kaydetmek ve bunun yerine [text] dosyasını sorgulamak olacaktır:

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

Gerçekte, gerçek dosya boyutunu bulmak için hesaplama yapılması gerekir.

Aynı zamanda tar, örneğin, yalnızca bir dosya boyutu veya adı elde etmek için tüm dekompresyon işleminde çalışmayı önlediğinden, büyük boyutlu yedeklemelerde yaptığım şeyle de aynı şeyi yapabilirsiniz.


2
Tüm dosyaların listesini almak için tar.gz'nin tamamen sıkıştırılması gerekmez mi?
frostschutz

Gerçekten de olması gerekiyor. Sıkıştırılmamış dosya boyutunu almayı düşünebilmemin tek yolu bu. Ardından tar, arşivde kayıtlı orijinal dosya boyutuna sahipsiniz. zipÖte yandan, farklı davrandığından emin değilim .

1
Bu noktada, OP wc -ckomutu da yapabilir .
Bratchley

Tabii @ Bratchley. Ancak tüm sonuçların alınması oldukça zaman alacaktır. Bu nedenle dosya önerileri kaydetmek için iki önerim var.

0

Ne dersin

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

numfmt --to=iec $(gzip -l file.gz|tail -n1|awk '{print $2}')

1
OP tarafından açıklandığı gibi, büyük dosyalar için işe yaramaz.
Stephen Kitt

-2
gunzip -c $file | wc -c

Bu uzun zaman alacaktır ancak bayt cinsinden son boyut verilecektir.


5
Bu tam olarak OP'nin yapmaktan kaçınmaya çalıştığı şeydir.
16'da
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.