2008-09-16 36 views

Trả lời

9

Từ MSDN về System.IO.Compression.GZipStream:

Lớp này đại diện cho định dạng dữ liệu gzip, trong đó sử dụng một thuật toán tiêu chuẩn công nghiệp cho tập tin nén và giải nén lossless.

Từ zlib FAQ:

Các gz * chức năng trong zlib mặt khác sử dụng định dạng gzip.

Vì vậy, zlib và GZipStream phải tương thích, nhưng chỉ khi bạn sử dụng các chức năng zlib để xử lý định dạng gzip.

System.IO.Compression.Deflate và zlib được cho là không tương thích được.

Nếu bạn cần xử lý tệp zip (có thể bạn không, nhưng ai đó có thể cần điều này), bạn cần sử dụng SharpZipLib hoặc thư viện bên thứ ba khác.

+1

tệp zip không giống với tệp nén zlib (thuật toán nén có thể giống nhau, nhưng tiêu đề không được) –

+0

Bạn nói đúng. Tôi sẽ chỉnh sửa câu trả lời của tôi. –

+21

re: "báo cáo không tương thích" liên quan đến zlib và DeflateStream. Chúng thực sự không tương thích được. Có ba RET IETF bao gồm không gian này: 1950 cho ZLIB, 1951 cho DEFLATE và 1952 cho GZIP. Deflate là thuật toán nén. ZLIB và GZIP là các định dạng riêng biệt, xác định siêu dữ liệu, còn gọi là "tiêu đề", áp dụng cho luồng nén. Thư viện zlib thực hiện cả ZLIB và GZIP. Để làm cho nó thú vị, cả ZLIB và GZIP đều có thể sử dụng DEFLATE làm cơ chế nén. Lớp DeflateStream tạo ra một luồng không có tiêu đề. Không có gì ngạc nhiên khi tất cả chúng ta đều bối rối. – Cheeso

2

Chúng chỉ nén dữ liệu bằng thuật toán zlib hoặc làm lệch hướng, nhưng không cung cấp đầu ra cho một số định dạng tệp cụ thể. Điều này có nghĩa là nếu bạn lưu trữ luồng vào ổ đĩa cứng, bạn sẽ không thể mở nó bằng ứng dụng (gzip hoặc winrar) vì tiêu đề tệp (số ma thuật, v.v.) không được bao gồm trong luồng, bạn nên tự viết chúng.

0

Tôi đồng ý với andreas. Có thể bạn sẽ không thể mở tệp trong một công cụ bên ngoài, nhưng nếu công cụ đó mong đợi một luồng, bạn có thể sử dụng nó. Bạn cũng sẽ có thể deflate các tập tin trở lại bằng cách sử dụng cùng một lớp nén.

3

gzip bị lệch + một số dữ liệu đầu trang/chân trang, như tổng kiểm tra và độ dài, v.v. Vì vậy, chúng không tương thích với ý nghĩa rằng một phương pháp có thể sử dụng luồng từ phương pháp khác, nhưng chúng sử dụng cùng một thuật toán nén.

6

Tôi đã sử dụng GZipStream để nén đầu ra từ .NET XmlSerializer và nó đã hoạt động hoàn hảo tốt để giải nén kết quả bằng gunzip (trong cygwin), winzip và một GZipStream khác.

Để tham khảo, đây là những gì tôi đã làm trong mã:

FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write); 
using (GZipStream gzStream = new GZipStream(fs, CompressionMode.Compress)) 
{ 
    XmlSerializer serializer = new XmlSerializer(typeof(MyDataType)); 
    serializer.Serialize(gzStream, myData); 
} 

Sau đó, để giải nén trong C#

FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read); 
using (Stream input = new GZipStream(fs, CompressionMode.Decompress)) 
{ 
    XmlSerializer serializer = new XmlSerializer(typeof(MyDataType)); 
    myData = (MyDataType) serializer.Deserialize(input); 
} 

Sử dụng 'file' tiện ích trong Cygwin tiết lộ rằng có thực sự là một sự khác biệt giữa cùng một tệp được nén với GZipStream và với GNU GZip (có thể là thông tin tiêu đề như những thông tin khác đã nêu trong chủ đề này). Tuy nhiên, sự khác biệt này dường như không quan trọng trong thực tế.

+1

hoạt động như sự quyến rũ! Tập dữ liệu lớn tôi đang sử dụng để kiểm tra hiệu suất đã được nén từ 55MB xuống còn 7,5MB, mà không làm giảm hiệu suất đáng chú ý. P.S. Nếu "tệp" được đổi tên thành "file.gz", tệp đó sẽ trở thành tệp lưu trữ hợp lệ hoàn toàn. Bạn thậm chí có thể sửa đổi nội dung của nó bằng cách sử dụng bất kỳ công cụ lưu trữ nào, và nó sẽ vẫn còn deserializeable bằng cách sử dụng phương pháp của bạn. – Soonts

14

DotNetZip bao gồm DeflateStream, ZlibStream và GZipStream, để xử lý RFC 1950, 1951 và 1952. Tất cả đều sử dụng thuật toán DEFLATE nhưng khung và byte tiêu đề khác nhau cho mỗi loại.

Là một lợi thế, các luồng trong DotNetZip không hiển thị anomaly of expanding data size dưới dạng nén, được báo cáo dựa trên các luồng được tích hợp sẵn.Ngoài ra, không có ZlibStream tích hợp, trong khi DotNetZip mang đến cho bạn điều đó, cho sự tương tác tốt với zlib.

12

Tôi đã gặp sự cố này với các đối tượng Git. Trong trường hợp cụ thể đó, chúng lưu trữ các đối tượng dưới dạng các đốm màu xì hơi với tiêu đề Zlib, được ghi lại trong RFC 1950. Bạn có thể làm cho một blob tương thích bằng cách làm cho một tập tin có chứa:

  • Hai byte tiêu đề (CMF và FLG từ RFC 1950) với các giá trị 0x78 0x01
    • CM = 8 = deflate
    • CINFO = 7 = cửa sổ 32Kb
    • bit
    • FCHECK = 1 = checksum cho tiêu đề này
  • Kết quả của C# DeflateStream
  • Một Adler32 checksum của dữ liệu đầu vào cho, định dạng DeflateStream lớn-endian (MSB đầu tiên)

tôi đã thực hiện riêng Adler thực hiện của tôi

public class Adler32Computer 
{ 
    private int a = 1; 
    private int b = 0; 

    public int Checksum 
    { 
     get 
     { 
      return ((b * 65536) + a); 
     } 
    } 

    private static readonly int Modulus = 65521; 

    public void Update(byte[] data, int offset, int length) 
    { 
     for (int counter = 0; counter < length; ++counter) 
     { 
      a = (a + (data[offset + counter])) % Modulus; 
      b = (b + a) % Modulus; 
     } 
    } 
} 

Và đó là khá nhiều nó .

1

Bắt đầu từ .NET Framework 4.5 lớp System.IO.Compression.DeflateStream sử dụng thư viện zlib.

Từ của MSDN article lớp:

Lớp này đại diện các thuật toán Deflate, mà là một thuật toán tiêu chuẩn công nghiệp cho tập tin nén và giải nén lossless. Bắt đầu với .NET Framework 4.5, lớp DeflateStream sử dụng thư viện zlib. Kết quả là, nó cung cấp một thuật toán nén tốt hơn và, trong hầu hết các trường hợp, một tệp nén nhỏ hơn nó cung cấp trong các phiên bản trước của Khuôn khổ .NET.

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