2009-07-17 41 views
11

Tôi muốn kết hợp hai hoặc nhiều luồng gzip mà không cần nén lại chúng.Cách kết hợp hai hoặc nhiều tệp gzip/luồng

Ý tôi là tôi đã nén thành A.gz và B thành B.gz, tôi muốn nén chúng thành một gzip đơn (A + B) .gz mà không nén lại một lần nữa, sử dụng C hoặc C++.

Một số lưu ý:

  • Thậm chí bạn có thể chỉ concat hai tập tin và gunzip sẽ biết làm thế nào để đối phó với họ, hầu hết các chương trình sẽ không thể để đối phó với hai khối.
  • Tôi đã từng thấy một ví dụ về mã thực hiện điều này bằng cách giải nén các tệp và sau đó thao tác gốc và nén lại nhanh hơn bình thường, nhưng vẫn yêu cầu hoạt động CPU O (n).
  • Bất hạnh Tôi không thể tìm thấy ví dụ này tôi đã tìm thấy một lần (nối bằng cách sử dụng giải nén chỉ), nếu ai đó có thể chỉ nó tôi sẽ rất tuyệt vời.

Lưu ý: nó không trùng lặp với this vì giải pháp được đề xuất không phù hợp với nhu cầu của tôi.

Clearification chỉnh sửa:

Tôi muốn concate nhiều pices HTML nén và gửi chúng đến trình duyệt như một trang, theo yêu cầu: "Accept-Encoding: gzip", với respnse "Content-Encoding: gzip "

Nếu luồng được concated đơn giản như cat a.gz b.gz >ab.gz, Gecko (firefox) và công cụ web KHTML chỉ nhận được phần đầu tiên (a); IE6 không hiển thị bất cứ thứ gì và Google Chrome hiển thị phần đầu tiên (a) một cách chính xác và phần thứ hai (b) làm rác (không giải nén).

Chỉ Opera xử lý tốt điều này.

Vì vậy, tôi cần tạo một luồng gzip duy nhất của nhiều đoạn và gửi chúng mà không cần nén lại.

Cập nhật: Tôi đã tìm thấy gzjoin.c trong ví dụ về zlib, nó chỉ sử dụng giải nén. Vấn đề là giải nén vẫn chậm hơn chúng đơn giản memcpy.

Nó vẫn nhanh hơn 4 lần sau đó nén gzip nhanh nhất. Nhưng nó không phải là đủ.

Điều tôi cần là tìm dữ liệu tôi cần lưu cùng với tệp gzip để không chạy quy trình giải nén và làm cách nào để tìm dữ liệu này trong quá trình nén.

+0

Bạn có thực sự muốn nén chúng hoặc chỉ ghép chúng vào cùng một tệp không? –

+0

Tôi muốn tạo một tệp nén/luồng/bộ nhớ nén của hai tệp nén/luồng/bộ nhớ nén khác của gzip mà không giải nén chúng, đồng bộ hóa chúng và nén chúng lại một lần nữa. – Artyom

+0

Xem phần giải thích trong bản chỉnh sửa. – Artyom

Trả lời

11

Nhìn vào các RFC1951RFC1952

Định dạng chỉ đơn giản là một dãy các thành viên, mỗi bộ gồm ba phần, một tiêu đề, dữ liệu và đoạn giới thiệu.Phần dữ liệu chính nó là một tập hợp các khối với mỗi khối có phần tiêu đề và dữ liệu.

Để mô phỏng hiệu ứng của gzipping kết quả của việc nối hai (hoặc nhiều tệp), bạn chỉ cần điều chỉnh tiêu đề (ví dụ như một đoạn cờ cuối) và đoạn giới thiệu chính xác và sao chép các phần dữ liệu.

Có sự cố, đoạn giới thiệu có CRC32 của dữ liệu chưa nén và tôi không chắc liệu đoạn mã này có dễ tính toán khi bạn biết CRC của các bộ phận hay không.

Chỉnh sửa: các nhận xét trong tệp gzjoin.c bạn tìm thấy ngụ ý rằng, trong khi có thể tính CRC32 mà không giải nén dữ liệu, có những thứ khác cần giải nén.

+1

Nếu bạn có CRC cho các phần, bạn có thể sử dụng chúng để tính CRC cuối cùng. Nếu tôi không nhầm, nếu bạn có Msg1 với Crc1 và Msg2 với Crc2, thì để tính toán crc của [Msg1, Msg2], bạn có thể tính toán crc của [Crc1, 0,0,0,0 ... (số 0 Msg2 length times)] và xor nó với Crc2. Có thể là bổ sung của một người sẽ được yêu cầu ở đâu đó nhưng ý tưởng là điều này. – eugensk00

2

Nếu tar ing họ không phải là ra câu hỏi (kể từ khi liên kết cat solution là không khả thi cho bạn):

tar cf A_B.gz.tar A.gz B.gz 

Sau đó, để có được chúng trở lại:

tar xf A_B.gz.tar 
+0

Không, tôi không nói về tar ở tất cả – Artyom

+1

Tôi thấy những gì bạn đang nói bây giờ. . . Bạn muốn làm tương đương với "gunzip A.gz & guzip B.gz & cat A B> C & gzip C.gz A B", nhưng không có giải nén, với hy vọng đạt được O (1) thời gian xử lý. gzip sẽ không thực hiện điều đó và tôi không biết liệu có tiện ích nào có thể. Nhưng ngay cả khi có, nó vẫn sẽ cần O (n) thời gian, vì nó sẽ phải (ít nhất) kiểm tra các tập tin nén để tìm ra cách để nén chúng. –

+0

Có vấn đề gì với việc tarring chúng, nó đạt được mọi thứ bạn muốn làm. –

2

Dường như nén bản gốc của từng tệp riêng lẻ do bạn thực hiện. Nó cũng có vẻ như kết quả mong muốn (ghép nối của một số phần) là đủ nhỏ để được gửi đến một trình duyệt web trong một trang. Trong trường hợp đó, mối quan tâm về hiệu quả của bạn dường như không chính đáng.

Xin lưu ý rằng (1) phương pháp tiếp cận gzjoin.c rất có khả năng là câu trả lời tốt nhất mà bạn có thể nhận được câu hỏi của bạn như đã nêu (2) nó là vi phẫu phức tạp được thực hiện bởi một trong những người khởi tạo gzip và có thể không đã bị thử nghiệm căng thẳng rộng rãi.

Hãy xem xét một cách tiếp cận đáng tin cậy có thể hiểu được nhàm chán: lưu trữ các phần gốc Không nén, sau đó chọn các phần yêu cầu, và nối và nén chúng. Lưu ý rằng tỷ lệ nén có thể tốt hơn so với tỷ lệ nén thu được bằng cách dán các mảnh nén nhỏ lại với nhau.

+0

Vâng, tôi là người khởi tạo của hai phần, vì vậy tôi thậm chí có thể lưu một số siêu dữ liệu với họ, hoặc đưa ra một số giả định. Vì vậy, tôi hiểu rằng gzjoin đơn giản và ít bị lỗi hơn, nhưng nó vẫn nhanh hơn 4 lần rồi đơn giản "gzip -1". Tôi cần memcpy gần tăng tốc. Ý tưởng: Tôi lưu trữ một số khối sẵn sàng và kết hợp chúng theo yêu cầu của người dùng. – Artyom

+0

Bạn chưa giải thích lý do tại sao bạn cần "memcpy near speedup" trên những gì có vẻ là một lượng nhỏ dữ liệu. Có lẽ bạn có thể cho chúng tôi biết có bao nhiêu trang bạn cần để phân phát mỗi giây và chúng lớn như thế nào. –

+0

Giả sử các trang và khối lớn và tải cực kỳ cao là . – Artyom

6

Hướng dẫn sử dụng gzip cho biết hai tệp gzip có thể được ghép nối khi bạn cố gắng.

http://www.gnu.org/software/gzip/manual/gzip.html#Advanced-usage

Vì vậy, có vẻ như các công cụ khác có thể bị phá vỡ. Như đã thấy trong báo cáo lỗi này. http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=97263

Ngoài việc gửi báo cáo lỗi cho từng nhà sản xuất trình duyệt và hy vọng họ tuân thủ, có lẽ chương trình của bạn có thể lưu vào bộ nhớ chung nhất của dữ liệu được yêu cầu.

Như những người khác đã đề cập đến bạn có thể thực hiện phẫu thuật: http://www.gzip.org/zlib/rfc-gzip.html

Và điều này đòi hỏi một CRC-32 của tập tin nén thức. Kích thước yêu cầu của tệp không nén có thể được tính toán dễ dàng bằng cách thêm độ dài của từng tệp phụ.

Ở cuối liên kết cuối cùng, có mã để tính toán hoạt động crc-32 có tên là update_crc.

Tính crc trên các tệp không nén mỗi khi quá trình của bạn chạy, có lẽ rẻ hơn chính thuật toán gzip.

+0

Nói về các thư viện .NET, tôi đã xác minh cá nhân rằng thư viện này hỗ trợ các tệp GZip nhiều phần: http://www.icsharpcode.net/opensource/sharpziplib/ – DenNukem

Các vấn đề liên quan