2009-06-08 4 views
5

캐시에 추가하기 전에 데이터베이스의 QUERYS에서 결과를 압축하려고합니다.gzip을 사용하여 .net 객체 인스턴스를 압축하는 방법

모든 참조 유형을 압축 할 수 있기를 원합니다.

내가 가지고 .. 스캇 Hanselman은의 블로그 게시물 http://shrinkster.com/173t

.NET 개체를 압축하기위한 아이디어를 기반으로 아이디어를 문자열을 압축이의 작업 버전?

내가 캐시에있는 객체가 단지 바이트 배열되기 때문에이 읽기 전용 캐시 될 것이라는 점을 알고있다 ..

답변

20

어떤 참조 형에 대해 작동하지 않습니다. 이것은 Serializable 유형에서 작동합니다. 파일에 파이프됩니다 압축 스트림에 BinaryFormatter를 연결 : 당신은 오히려 파일에 쓰는 것보다, 메모리에 내용을 유지하기 위해 MemoryStream을 사용할 수

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(); 
} 

. 그러나 이것이 캐시를위한 효과적인 솔루션이라고는 생각하지 않습니다.

+1

감사합니다. 정말로 도움이되었습니다. 압축 해제 된 모양은 어떨까요? 이전에는 BinaryFormatter를 사용하지 않았습니다. –

+0

내 코드에 쉽게 복사하고 붙여 넣을 수있게 해주셔서 감사합니다. 자주 형식을 지정하여 이제는 Google에서 쉽게 찾을 수있는 스 니펫입니다. +1 –

3

어떤 종류의 개체를 캐시에 넣고 있습니까? 유형이 지정된 객체입니까? 또는 DataTable 같은 것들? DataTable의 경우 GZipStream을 통해 압축 된 XML로 저장하십시오. 유형이 지정된 (엔티티) 객체의 경우 직렬화해야 할 수 있습니다.

당신은 BinaryFormatterGZipStream을 사용할 수 있습니다 또는 당신은 단지 이미 매우 컴팩트 protobuf-net 직렬화 (무료) 같은 것을 사용할 수 있습니다 (- 조밀 한 바이너리의 전형적인 GZipStream를 추가하면 일반적으로 데이터 한다). 특히, protobuf-net과 같은 것들의 이점은 직렬화 해제 중에 CPU를 비용을 지불하지 않고도 크기를 줄일 수 있다는 것입니다. some tests에서 앞에 GZipStream을 더하면 BinaryFormatter보다 4 배 빠릅니다. 추가 시간을 GZip의 경우 BinaryFormatter에 추가하면 상당의 마진까지 이깁니다.

2

오늘 내 앱용 GZipStream 지원을 추가 했으므로 여기에서 일부 코드를 공유 할 수 있습니다.

직렬화 :

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); 
     } 
    } 
} 

역 직렬화 :

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); 
     } 
    } 
} 

참고 : CryptoStream을 사용하는 경우, 때문에, 당신은 체인 (UN) 압축하는과 (드) 이쪽을 암호화 등 것이 좀 중요하다 암호화하기 전에 데이터에서 잡음이 생기기 전에 엔트로피를 잃고 싶을 것입니다.

관련 문제