วิธีที่เร็วที่สุดในการจัดการขนาดไฟล์ที่ไม่บีบอัดของ GZIPPED ขนาดใหญ่


24

เมื่อไฟล์ถูก gzipped จะมีวิธีสอบถามอย่างรวดเร็วเพื่อบอกว่าขนาดไฟล์ที่ไม่บีบอัดคืออะไร (โดยไม่ต้องคลายการบีบอัด) โดยเฉพาะอย่างยิ่งในกรณีที่ไฟล์ที่ไม่มีการบีบอัด> 4GB

ตาม RFC https://tools.ietf.org/html/rfc1952#page-5คุณสามารถสอบถาม 4 ไบต์สุดท้ายของไฟล์ได้ แต่หากไฟล์ที่ไม่มีการบีบอัดเป็น> 4GB ค่าจะแสดงถึงuncompressed value modulo 2^32

ค่านี้สามารถเรียกคืนได้ด้วยการเรียกใช้gunzip -l foo.gzอย่างไรก็ตามคอลัมน์ "ไม่มีการบีบอัด" จะมีuncompressed value modulo 2^32อีกครั้งซึ่งน่าจะเป็นเพราะมันอ่านส่วนท้ายตามที่อธิบายไว้ข้างต้น

ฉันแค่สงสัยว่ามีวิธีการรับขนาดไฟล์ที่ไม่บีบอัดโดยไม่ต้องแตกไฟล์ก่อนซึ่งจะเป็นประโยชน์อย่างยิ่งในกรณีที่ไฟล์ gzipped มีข้อมูล 50GB + และใช้เวลาสักครู่ในการคลายบีบอัดโดยใช้วิธีการเช่น gzcat foo.gz | wc -c


แก้ไข:ข้อ จำกัด 4GB ได้รับการยอมรับอย่างเปิดเผยในmanหน้าของgzipยูทิลิตี้ที่มาพร้อมกับ 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.

2
+1 คำถามที่ดี! ฉันสงสัยว่าคำตอบคือไม่รูปแบบส่วนหัวนั้นได้รับการออกแบบในเวลาก่อนที่ขนาดไฟล์ดังกล่าวคาดว่าจะได้ กำลังคิดจะgzipต้องมีอายุมากกว่าผู้ใช้จำนวนมากในชุมชนนี้!
Celada

2
gzipออกมาในปี 1992 ฉันจะแปลกใจถ้ามีเด็กอายุ 23 ปีสัญจรไปมาแถวนี้ ฉันแน่ใจว่ามีบางอย่าง แต่จากสิ่งที่ฉันสามารถบอกอายุเฉลี่ยอยู่ที่ประมาณ 30-35
Bratchley

2
อาจเป็นเวลาที่ดีในการเปลี่ยนไปใช้xzซึ่งไม่มีข้อ จำกัด GNU xzจะเปลี่ยนไปใช้
Stéphane Chazelas

@ StéphaneChazelasน่าสนใจ น่าเสียดายที่ไฟล์ที่ฉันสนใจอยู่นอกเหนือการควบคุมของฉัน (เช่นเราได้รับการบีบอัดไฟล์) แต่ดูเหมือนว่าxz จะ 'แก้ปัญหานี้'
djhworld

คำตอบ:


11

ฉันเชื่อว่าวิธีที่เร็วที่สุดคือการแก้ไขgzipเพื่อให้การทดสอบในโหมด verbose ส่งผลให้จำนวนไบต์แตกออกมา ในระบบของฉันฉันได้รับไฟล์ 7761108684- ไบต์

% 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 (1.6 มีให้บริการใน Debian) แพตช์จะเป็นดังนี้:

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

มันยังคงสร้างข้อมูลจริงภายในหรือ-tปรับให้เหมาะสมแล้วในเรื่องนั้น? การปรับปรุงมีขนาดเล็กพอที่จะทำให้ดูเหมือนว่าคุณได้บันทึกเฉพาะเวลาส่งออกเท่านั้น
frostschutz

ใช่มันจำเป็นต้องลดขนาดทุกอย่างเพื่อหาขนาดดั้งเดิม ... ดังนั้นนี่เป็นการประหยัดเวลาเอาต์พุตเท่านั้น แต่ฉันคิดว่านั่นคือทั้งหมดที่สามารถบันทึกได้
Stephen Kitt

น่าสนใจใช่ฉันคิดว่าคุณจะต้องเปลี่ยนรหัสเพื่อให้มันใช้งานได้จริง โชคไม่ดีที่อินสแตนซ์ของฉันไฟล์ที่ฉันสนใจไม่ได้อยู่ในการควบคุมของฉันจริง ๆ ฉันได้รับไฟล์จากบุคคลภายนอกดังนั้นจึงไม่สามารถบีบอัดไฟล์เหล่านั้นได้ตั้งแต่แรก ฉันคิดว่าวิธีเดียวที่จะรองรับได้อย่างเต็มที่> ไฟล์ 4GB คือการแพตช์ gzip ให้มีส่วนท้าย 12 ไบต์, 4 ไบต์สำหรับ CRC และ 8 ไบต์ (64 บิต) สำหรับขนาดไฟล์ อย่างไรก็ตามสิ่งนี้จะทำลายความเข้ากันได้ย้อนหลังกับ gzips ที่มีอยู่!
djhworld

วิธีแก้ปัญหาที่ฉันให้ไว้ข้างต้นไม่เกี่ยวข้องกับการบีบอัดไฟล์ในตอนแรกแม้ว่าฉันจะกำลังทำงานอยู่gzipก็ตาม ฉันเพิ่งรันgzipไฟล์บีบอัดซึ่งไม่ได้บีบอัดไฟล์อีกครั้งมันแค่ตรวจสอบพวกเขา (แพทช์เป็นแนวคิดที่รวดเร็วและสกปรกมันต้องมีการเปลี่ยนแปลงอีกเล็กน้อยในการทำงานด้วยgunzip)
Stephen Kitt

@StephenKitt อ่าน่าสนใจ! การแฮ็คที่ดีขึ้น / สกปรกยิ่งขึ้นก็คือการฝังข้อมูลนั้นไว้ในFCOMMENTฟิลด์ วิธีนั้นผู้ใช้สามารถสอบถามช่วงไบต์เพื่อดึงข้อมูล มันจะมีประโยชน์ในกรณีของฉันโดยเฉพาะอย่างยิ่งสำหรับรายการที่เก็บไว้ใน Amazon S3
djhworld

0

หากคุณต้องการขนาดของไฟล์บีบอัดหรือชุดของไฟล์ที่ทางออกที่ดีที่สุดของคุณคือการใช้งานtar -zหรือtar -jแทนที่จะgzipเป็นtarมีขนาดไฟล์บีบอัด ใช้lesspipeเพื่อดูรายการไฟล์:

aptitude install lesspipe
lesspipe <compressed file> | less

หากlessมีการกำหนดค่าให้ใช้lesspipe:

less <compressed file>

แค่จำไว้ว่ามันอาจใช้เวลานานมาก อย่างไรก็ตามระบบของคุณยังคงตอบสนองซึ่งช่วยให้คุณฆ่ากระบวนการคลายการบีบอัด

อีกวิธีหนึ่งคือการบันทึกอัตราส่วนการบีบอัดและการสืบค้นที่ [text] ไฟล์แทน:

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

มันต้องมีการคำนวณเพื่อหาขนาดไฟล์จริง

คุณสามารถทำเช่นเดียวกันกับtarซึ่งในความเป็นจริงสิ่งที่ฉันทำกับการสำรองข้อมูลขนาดใหญ่เพราะมันป้องกันไม่ให้ทำงานผ่านกระบวนการคลายการบีบอัดทั้งหมดเพื่อให้ได้ขนาดหรือชื่อไฟล์เท่านั้น


2
tar.gz ไม่จำเป็นต้องทำการแตกไฟล์อย่างสมบูรณ์เช่นกันเพื่อรับรายชื่อไฟล์ทั้งหมดหรือไม่?
frostschutz

แน่นอนมันจะต้องมี นี่เป็นวิธีเดียวที่ฉันสามารถนึกได้ว่าจะได้ขนาดไฟล์ที่ไม่บีบอัด ด้วยtarคุณมีขนาดไฟล์เดิมเข้าสู่ระบบในที่เก็บ ในทางกลับกันฉันไม่แน่ใจว่าzipจะมีพฤติกรรมที่แตกต่างออกไป

1
ณ จุดนั้น OP อาจทำwc -cคำสั่งด้วยเช่นกัน
Bratchley

@ แบรดลีย์แน่นอน แต่ต้องใช้เวลานานพอสมควรกว่าจะได้ผลลัพธ์ทั้งหมด ดังนั้นสองข้อเสนอแนะของฉันเพื่อบันทึกขนาดไฟล์

0

เกี่ยวกับอะไร

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

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

1
ไม่สามารถใช้งานกับไฟล์ขนาดใหญ่ตามที่อธิบายโดย OP
สตีเฟ่น Kitt

-2
gunzip -c $file | wc -c

การดำเนินการนี้จะใช้เวลานาน แต่จะให้ขนาดสุดท้ายเป็นไบต์


5
ตรงนี้เป็นสิ่งที่ OP พยายามหลีกเลี่ยงที่จะทำ
ลด
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.