2009-06-08 24 views
5

Tôi muốn nén kết quả từ QUERYS của cơ sở dữ liệu trước khi thêm chúng vào bộ nhớ cache.Cách nén một đối tượng .net bằng cách sử dụng gzip

Tôi muốn có thể nén bất kỳ loại tham chiếu nào.

Tôi có một phiên bản làm việc này để nén các chuỗi .. ý tưởng dựa trên bài đăng blog của Scott Hanselman 's http://shrinkster.com/173t

bất kỳ ý tưởng để nén một đối tượng .net?

Tôi biết rằng nó sẽ là một chỉ bộ nhớ cache đọc từ các đối tượng trong bộ nhớ cache sẽ chỉ là mảng byte ..

Trả lời

20

này sẽ không làm việc cho bất kỳ loại tham khảo. Điều này sẽ hoạt động cho các loại Serializable. Treo lên một BinaryFormatter đến một dòng nén được cấp nước tập trung vào một tệp:

var formatter = new BinaryFormatter(); 
using (var outputFile = new FileStream("OutputFile", FileMode.CreateNew)) 
using (var compressionStream = new GZipStream(
         outputFile, CompressionMode.Compress)) { 
    formatter.Serialize(compressionStream, objToSerialize); 
    compressionStream.Flush(); 
} 

Bạn có thể sử dụng một MemoryStream để giữ các nội dung trong bộ nhớ, chứ không phải bằng văn bản cho một tập tin. Tôi nghi ngờ đây thực sự là một giải pháp hiệu quả cho một bộ nhớ cache, tuy nhiên.

+1

cảm ơn bạn điều này đã thực sự hữu ích, những gì sẽ giải nén trông giống như ... không bao giờ được sử dụng BinaryFormatter trước. –

+0

Cảm ơn bạn đã thực hiện việc này dễ dàng sao chép + có thể dán vào mã của tôi. Tôi định dạng mọi thứ thường xuyên đủ để bây giờ chỉ là một đoạn trích mà tôi có thể dễ dàng tìm thấy trên Google. +1 –

3

Bạn sắp xếp loại đối tượng nào vào bộ nhớ cache? Họ đã gõ đối tượng? Hoặc những thứ như DataTable? Đối với DataTable, có thể lưu trữ dưới dạng xml được nén qua GZipStream. Đối với các đối tượng đã nhập (thực thể), có thể bạn sẽ cần phải tuần tự hóa chúng.

Bạn có thể sử dụng BinaryFormatterGZipStream, hoặc bạn chỉ có thể sử dụng một cái gì đó giống như protobuf-net serialization (miễn phí) là đã rất nhỏ gọn (thêm GZipStream thường làm cho các dữ liệu lớn - đó là đặc trưng của nhị phân dày đặc). Đặc biệt, lợi thế của những thứ như protobuf-net là bạn nhận được kích thước đã giảm mà không phải trả chi phí CPU để giải nén nó trong quá trình deserialization. Trong some teststrước khi thêm GZipStream, nhanh hơn 4 lần so với BinaryFormatter. Thêm thời gian bổ sung vào BinaryFormatter cho GZip và nó sẽ giành chiến thắng theo tỷ lệ đáng kể.

2

Tôi vừa thêm hỗ trợ GZipStream cho ứng dụng của mình hôm nay, vì vậy tôi có thể chia sẻ một số mã tại đây;

serialization:

using (Stream s = File.Create(PathName)) 
{ 
    RijndaelManaged rm = new RijndaelManaged(); 
    rm.Key = CryptoKey; 
    rm.IV = CryptoIV; 
    using (CryptoStream cs = new CryptoStream(s, rm.CreateEncryptor(), CryptoStreamMode.Write)) 
    { 
     using (GZipStream gs = new GZipStream(cs, CompressionMode.Compress)) 
     { 
      BinaryFormatter bf = new BinaryFormatter(); 
      bf.Serialize(gs, _instance); 
     } 
    } 
} 

Deserialization:

using (Stream s = File.OpenRead(PathName)) 
{ 
    RijndaelManaged rm = new RijndaelManaged(); 
    rm.Key = CryptoKey; 
    rm.IV = CryptoIV; 
    using (CryptoStream cs = new CryptoStream(s, rm.CreateDecryptor(), CryptoStreamMode.Read)) 
    { 
     using (GZipStream gs = new GZipStream(cs, CompressionMode.Decompress)) 
     { 
      BinaryFormatter bf = new BinaryFormatter(); 
      _instance = (Storage)bf.Deserialize(gs); 
     } 
    } 
} 

Chú ý: nếu bạn sử dụng CryptoStream, nó là khá quan trọng mà bạn chuỗi (un) nén và (de) crypting đúng cách này, bởi vì bạn sẽ muốn mất mã hóa entropy TRƯỚC KHI tạo ra nhiễu từ dữ liệu của bạn.

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