Cách nhanh nhất để xử lý kích thước không nén của tệp GZIPPED lớn


24

Khi một tệp được nén, có một cách nhanh chóng truy vấn nó để cho biết kích thước tệp không nén là gì (không giải nén nó), đặc biệt trong trường hợp tệp không nén có kích thước> 4GB.

Theo RFC https://tools.ietf.org/html/rfc1952#page-5 bạn có thể truy vấn 4 byte cuối cùng của tệp, nhưng nếu tệp không nén là> 4GB thì giá trị chỉ đại diện chouncompressed value modulo 2^32

Giá trị này cũng có thể được lấy bằng cách chạy gunzip -l foo.gz, tuy nhiên cột "không nén" chỉ chứa uncompressed value modulo 2^32lại, có lẽ là khi nó đọc phần chân trang như được mô tả ở trên.

Tôi chỉ tự hỏi liệu có cách nào để có được kích thước tệp không nén mà không phải giải nén nó trước không, điều này sẽ đặc biệt hữu ích trong trường hợp các tệp được nén có chứa 50GB + dữ liệu và sẽ mất một thời gian để giải nén bằng các phương thức như gzcat foo.gz | wc -c


EDIT: Giới hạn 4GB được xác nhận công khai trong mantrang của gziptiện ích đi kèm với 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 câu hỏi hay! Tôi nghi ngờ câu trả lời là không, định dạng tiêu đề được thiết kế trong một thời gian trước khi kích thước tệp như vậy được dự đoán. Suy nghĩ về nó, gzipphải già hơn nhiều người dùng trong cộng đồng này!
Celada 7/2/2015

2
gzipxuất hiện vào năm 1992. Tôi sẽ rất ngạc nhiên nếu có nhiều người 23 tuổi lang thang ở đây. Tôi chắc chắn có một số nhưng từ những gì tôi có thể nói tuổi trung bình là khoảng 30-35.
Bratchley 7/2/2015

2
Có thể là thời điểm tốt để chuyển sang xzcái không có giới hạn đó. GNU đang chuyển sang xz.
Stéphane Chazelas 7/215

@ StéphaneChazelas Thú vị. Thật không may, các tệp tôi quan tâm nằm ngoài tầm kiểm soát của tôi (tức là chúng tôi nhận được chúng được nén), nhưng chắc chắn có vẻ như xz sẽ giải quyết được vấn đề này.
djhworld 7/2/2015

Câu trả lời:


11

Tôi tin rằng cách nhanh nhất là sửa đổi gzipđể thử nghiệm trong chế độ dài dòng cho ra số lượng byte được giải nén; trên hệ thống của tôi, với tệp 7761108684 byte, tôi nhận được

% 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

Để sửa đổi gzip (1.6, như có sẵn trong Debian), bản vá như sau:

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

Liệu nó vẫn xây dựng dữ liệu thực tế trong nội bộ, hay -tđã được tối ưu hóa trong vấn đề đó? Sự cải thiện đủ nhỏ để khiến nó trông giống như bạn chỉ tiết kiệm thời gian đầu ra.
frostschutz 7/2/2015

Vâng, nó cần giải nén mọi thứ để tìm ra kích thước ban đầu ... Vì vậy, điều này chỉ tiết kiệm thời gian đầu ra, nhưng tôi nghĩ đó là tất cả những gì có thể được lưu.
Stephen Kitt

Thật thú vị, vâng tôi đã nghĩ rằng bạn sẽ cần phải thay đổi mã để thực sự làm việc này. Thật không may, trong trường hợp của tôi, các tệp mà tôi quan tâm không thực sự nằm trong tầm kiểm soát của tôi, tôi nhận được chúng từ một bên ngoài nên sẽ không thể nén chúng ngay từ đầu. Tôi nghĩ cách duy nhất để hỗ trợ đầy đủ các tệp> 4GB là vá gzip để có chân trang 12 byte, 4 byte cho CRC và 8 byte (64 bit) cho kích thước tệp. Tuy nhiên, điều này sẽ phá vỡ khả năng tương thích ngược với các gzips hiện có!
djhworld 7/2/2015

Giải pháp tôi đưa ra ở trên không liên quan đến việc nén các tệp ban đầu, mặc dù tôi đang chạy gzip; Tôi chỉ chạy gziptrên các tệp nén mà không nén lại chúng, nó chỉ xác minh chúng. (Bản vá là một bằng chứng nhanh chóng và bẩn thỉu, nó cần thêm một vài thay đổi để làm việc gunzip.)
Stephen Kitt

@StephenKitt Ah thú vị! Một hack thậm chí tốt hơn / bẩn hơn sẽ là nhúng dữ liệu đó vào FCOMMENTtrường. Bằng cách đó, người dùng có thể truy vấn một phạm vi byte để lấy dữ liệu đó. Điều này sẽ hữu ích trong trường hợp của tôi, đặc biệt đối với các mặt hàng được lưu trữ trong Amazon S3
djhworld 7/215

0

Nếu bạn cần kích thước của một tập tin nén hoặc bộ các tập tin, đặt cược tốt nhất của bạn là để sử dụng tar -zhoặc tar -jthay vì gzipnhư tarbao gồm các tập tin nén kích thước. Sử dụng lesspipeđể xem danh sách các tập tin:

aptitude install lesspipe
lesspipe <compressed file> | less

Nếu lessđược cấu hình để sử dụng lesspipe:

less <compressed file>

Chỉ cần nhớ rằng nó có thể mất một thời gian rất dài mặc dù. Tuy nhiên, hệ thống của bạn vẫn phản hồi nhanh, cho phép bạn giết quá trình giải nén.

Một cách tiếp cận khác là ghi nhật ký tỷ lệ nén và truy vấn tệp [văn bản] đó:

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

Nó đòi hỏi tính toán để tìm kích thước tập tin thực sự mặc dù.

Bạn cũng có thể làm tương tự với tar, thực tế là những gì tôi làm với các bản sao lưu có kích thước lớn vì nó ngăn không cho chạy qua toàn bộ quá trình giải nén để chỉ lấy kích thước tệp hoặc tên chẳng hạn.


2
Không phải tar.gz cũng phải được giải nén hoàn toàn để có được danh sách tất cả các tệp sao?
frostschutz 7/2/2015

Quả thực nó phải như vậy. Đây là cách duy nhất tôi có thể nghĩ ra để có được kích thước tệp không nén. Với tarbạn có kích thước tập tin gốc được đăng nhập vào kho lưu trữ. zipMặt khác, tôi không chắc chắn sẽ cư xử khác đi.

1
Tại thời điểm đó, OP cũng có thể thực hiện wc -clệnh.
Bratchley 7/2/2015

@Bratchley tất nhiên. Nhưng nó sẽ mất một khoảng thời gian đáng kể để có được tất cả các kết quả. Do đó hai đề nghị của tôi để đăng nhập kích thước tập tin.

0

Thế còn

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

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

1
Điều đó không hoạt động đối với các tệp lớn, như được giải thích bởi OP.
Stephen Kitt

-2
gunzip -c $file | wc -c

Điều này sẽ mất nhiều thời gian, nhưng sẽ cung cấp cho bạn kích thước cuối cùng theo byte.


5
Đây chính xác là những gì OP đang cố gắng tránh phải làm.
depquid
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.