어떻게 c\#에서 Zlib 압축 과 압축 을 풀 수 있 습 니까?

소개 하 다.
최근 에 c\#로 게임 의 압축 파일 편집 도 구 를 개발 하려 면 Zlib 표준 Deflate 알고리즘 으로 데 이 터 를 압축 해제 해 야 합 니 다.StackOverflow 를 한 바퀴 둘 러 보 니 c\#가 자주 사용 하 는 방식 은 마이크로소프트 가 제공 하 는 System.IO.Compression,zlib.net,그리고 ICSharpCode 의 SharpZipLib 인 것 으로 나 타 났 다.저 는 간단 한 테스트 와 포장 을 했 습 니 다.여기 서 성과 와 개인 적 인 견 해 를 공유 하 겠 습 니 다.
System.IO.Compression
일반적으로 c\#개발 을 사용 할 때 마이크로소프트 가 공식 적 으로 제공 할 수 있 는 도 구 를 사용 할 수 있 습 니 다.하 나 는 bug 가 적 고 유지 가 안정 적 입 니 다.그 밖 에 정부 가 제공 하 는 방안 은 최적화 에 있어 제3자 도구 보다 높다.
.NET Framework 4.5 부터 System.IO.Compression.Deflate Stream 에서 도 Zlib 를 사용 하여 Deflate 형식의 압축 과 압축 을 풀 었 지만 테스트 를 통 해 압축 과 압축 을 풀 었 습 니 다.결 과 는 다른 Zlib 라 이브 러 리 와 다 릅 니 다.
자세히 살 펴 보면 DeflateStream 으로 압축 한 데이터 의 시작 은 Zlib 로 압축 한 데이터 보다 두 바이트 가 적 고 끝 은 Zlib 보다 네 바이트 가 적다.이 출력 형식 은 Raw Deflate 라 고 합 니 다.
검 사 를 통 해 C\#에서 제공 하 는 Deflate Stream 은 이러한 Raw Deflate 로 압축 하거나 압축 을 풀 수 있 을 뿐 표준 Zlib Deflate 형식 을 처리 할 수 없습니다(단,스스로 생 성 할 수 있다 고 합 니 다).그러나 반대로 Zlib 는 헤드 데이터 가 포함 되 지 않 은 Raw Deflate 를 처리 하거나 생 성 할 수 있 습 니 다.
물론 header 와 trailer 를 수 동 으로 추가 할 수도 있 습 니 다.마지막 링크 를 읽 을 수 있 는 참고 자 료 를 어떻게 추가 하 는 지 는 특별히 중요 하지 않 기 때문에 게 으 름 을 피 웠 습 니 다.
다음은 제 가 이 방법 으로 간단하게 포장 한 압축 과 압축 해제 데이터 의 코드 입 니 다.

//   System.IO.Compression  Deflate  
public static byte[] MicrosoftCompress(byte[] data)
{
    MemoryStream uncompressed = new MemoryStream(data); //              ;           ,   FileStream   
    MemoryStream compressed = new MemoryStream();
    DeflateStream deflateStream = new DeflateStream(compressed, CompressionMode.Compress); //   :                          
    uncompressed.CopyTo(deflateStream); //   CopyTo              ;     Write      
    deflateStream.Close();  //  Close ,      Finish   Flush   。
    byte[] result = compressed.ToArray();
    return result;
}

//   System.IO.Compression  Deflate  
public static byte[] MicrosoftDecompress(byte[] data)
{
    MemoryStream compressed = new MemoryStream(data);
    MemoryStream decompressed = new MemoryStream();
    DeflateStream deflateStream = new DeflateStream(compressed, CompressionMode.Decompress); //   :                  ,            
    deflateStream.CopyTo(decompressed); 
    byte[] result = decompressed.ToArray();
    return result;
}
zlib.net
zlib.net 은 매우 작은 크기 의 오픈 소스 의 제3자 도구 입 니 다.본인 의 유한 한 연구 와 이 해 를 통 해 이 라 이브 러 리 는 사실은 반제품 과 같 고 많은 기능 이 완선 되 지 않 지만 장점 은 매우 가 볍 고 c++엔 드 와 boost:iostreams:zlib 효과 가 같다 는 것 입 니 다.
다음은 zlib.net 에서 제공 하 는 ZOutputStream 류 로 데 이 터 를 압축 하 는 코드 입 니 다.

public static byte[] ZLibDotnetCompress(byte[] data)
{
    MemoryStream compressed = new MemoryStream();
    ZOutputStream outputStream = new ZOutputStream(compressed, 2); 
    outputStream.Write(data, 0, data.Length); //         Write           ;             
    outputStream.Close();
    byte[] result = compressed.ToArray();
    return result;
}
다음은 zlib.net 에서 제공 하 는 ZInputStream 클래스 로 데 이 터 를 압축 해제 하 는 코드 입 니 다.

public static byte[] ZLibDotnetDecompress(byte[] data, int size)
{
    MemoryStream compressed = new MemoryStream(data);
    ZInputStream inputStream = new ZInputStream(compressed);
    byte[] result = new byte[size];   //   ZInputStream     BinaryReader   Stream,            buffer     read       。
    inputStream.read(result, 0, result.Length); //       read       
    return result;
}
read 를 통 해 압축 해제 후의 데 이 터 를 가 져 와 야 합 니 다.또한 압축 해제 방법 을 호출 할 때 외부 buffer 를 미리 제공 하여 출력 된 데 이 터 를 저장 해 야 합 니 다.이 buffer 의 크기 가 문제 입 니 다.
이 를 사용 하려 면 압축 된 데 이 터 를 저장 하 는 것 외 에 압축 되 지 않 는 위치 에 압축 전 크기 의 데 이 터 를 추가 하 는 것 을 권장 합 니 다.
그러나 전체적으로 개인 은 이 도 구 를 사용 하 는 것 을 권장 하지 않 는 다.
https://github.com/zyborg/zlib.net
http://www.componentace.com/zlib_.NET.htm
SharpZipLib
제 가 최종 적 으로 선택 한 것 은 SharpZipLib 입 니 다.(편집:당시 속도 테스트 를 하지 않 았 고 압축 을 풀 어야 할 파일 이 그리 크 지 않 았 으 며 속도 도 중요 하지 않 았 습 니 다.그렇지 않 았 다 면 이 방안 을 선택 하 는 것 을 추천 하지 않 았 습 니 다.)
ICSharpCode 는 ILSpy 를 개발 한 팀 답 게 SharpZipLib 은 강력 한 기능 을 제공 하면 서 사용 하기에 도 편리 하 다.주제 에 한 하여 데이터 흐름 을 Deflate 형식 으로 압축 하 는 것 만 논의 합 니 다.
쉽게 말 하면,당신 이 해 야 할 일 은 Deflater Output Stream 을 통 해 압축 하고,Inflater Input Stream 을 통 해 압축 을 푸 는 것 입 니 다.압축 과 압축 을 두 가지 다른 종류 로 나 누 는 것 을 제외 하고,다른 조작 방식 은 System.IO.Compression.Deflate Stream 과 완전히 같 을 수 있 습 니 다.
또한 압축 과 압축 해제 결 과 는 Zlib 공식 라 이브 러 리 를 직접 사용 하 는 것 과 똑 같 습 니 다.다른 프로그램 을 보조 하 는 도 구 를 개발 할 때 머리 와 꼬리 데이터 문 제 를 걱정 하지 않 아 도 됩 니 다.매우 편리 한 편 입 니 다.
다음은 제 가 이 방안 을 사용 하여 간단하게 포장 하 는 방법 입 니 다.

public static byte[] SharpZipLibCompress(byte[] data)
{
    MemoryStream compressed = new MemoryStream();
    DeflaterOutputStream outputStream = new DeflaterOutputStream(compressed);
    outputStream.Write(data, 0, data.Length);
    outputStream.Close();
    return compressed.ToArray();
}

public static byte[] SharpZipLibDecompress(byte[] data)
{
    MemoryStream compressed = new MemoryStream(data);
    MemoryStream decompressed = new MemoryStream();
    InflaterInputStream inputStream = new InflaterInputStream(compressed);
    inputStream.CopyTo(decompressed);
    return decompressed.ToArray();
}
속도 대비
몇 가지 방법 이 압축 과 압축 해제 효율 에서 의 우열 을 비교 하기 위해 서 나 는 두 조 의 데 이 터 를 준비 하여 간단 한 테스트 를 했다.
첫 번 째 그룹 은 짧 은 데이터 로 간단 한 문자열 입 니 다."this is just a string for testing,see how this compression thing works."
2 조 는 긴 데이터 로 인터넷 에서 다운로드 한 영문 판'얼음 과 불의 노래:권력 의 게임'txt 텍스트 로 크기 는 약 1.7mb 이다.
나 는 각각 각 방법 으로 짧 은 데 이 터 를 1000 번 압축 하고 압축 을 풀 었 으 며 긴 데 이 터 는 100 번 이 었 다.최종 결 과 는 다음 과 같다.

Length of Short Data: 144
Length of Long Data: 1685502

============================================
Compress and decompress with Microsoft Zlib Compression (1000 times): 54
Compress and decompress with Microsoft Zlib Compression (long data 100 times): 7924

============================================
Compress and decompress with Zlib.net Compression (1000 times): 254
Compress and decompress with Zlib.net Compression (long data 100 times): 9924

============================================
Compress and decompress with SharpZipLib Compression (1000 times): 442
Compress and decompress with SharpZipLib Compression (long data 100 times): 26782
긴 데이터 든 짧 은 데이터 의 압축 과 압축 해제 든 System.IO.Compression 에서 제공 하 는 방법 은 모두 다른 두 가지 방법 보다 우수 하 다 는 것 을 알 수 있다.
Zlib.net 은 속도 상의 열세 가 뚜렷 하지 않 고 같은 알고리즘 인 SharpZipLib 는 두 세 배 에서 세 배의 시간 이 걸린다.
총결산
결국 예상대로 마이크로소프트 가 공식 적 으로 제공 한 System.IO.Compression 의 방법 은 속도 적 으로 현저 한 장점 을 가진다.Deflate 의 두미 정 보 는 제공 되 지 않 지만 스스로 생 성 할 수 있 는 방법 을 생각 할 수 있 고 이 단점 은 기본적으로 완전히 무시 할 수 있다.Zlib.net 은 속도 적 으로 도 잘 표현 되 고 Deflate 압축 의 두미 정보 도 생 성 되 지만 포장 이 조잡 해 사용 하기에 상대 적 으로 불편 하 다.그러나 SharpZipLib 는 안 타 깝 게 도 다른 모든 면 에서 편리 하지만 속도 상의 결함 은 상당히 치 명 적 이다.RawDeflate 가 아 닌 Deflate 가 필요 하거나 사용 해 야 한다.Net Framework 가 4.5 보다 빠 를 때(운영 중 시간 소모 가 중요 하지 않 음)게 으 름 을 피 워 사용 할 수 밖 에 없다.
참고 와 연신
Zlib 에 대하 여
https://zlib.net/
Deflate 와 Raw Deflate 에 대하 여
https://stackoverflow.com/questions/37845440/net-deflatestream-vs-linux-zlib-difference
https://www.ietf.org/rfc/rfc1950.txt
https://www.ietf.org/rfc/rfc1951.txt
CSharp System.IO.Compression.Deflate Stream 에 대하 여
https://docs.microsoft.com/en-us/dotnet/api/system.io.compression.deflatestream?view=net-5.0
개발 자 중 한 명인 Mark Adler 가 StackOverflow 에서 의 대답
deflate 와 copress 함수 의 차이
https://stackoverflow.com/questions/10166122/zlib-differences-between-the-deflate-and-compress-functions/10168441#10168441
헤더 와 trailer 를 수 동 으로 추가 하 는 방법
https://stackoverflow.com/questions/39939869/data-format-for-system-io-compression-deflatestream
이상 은 어떻게 c\#에서 Zlib 압축 과 압축 을 풀 수 있 는 지 에 대한 상세 한 내용 입 니 다.c\#Zlib 압축 과 압축 을 풀 수 있 는 자 료 는 우리 의 다른 관련 글 에 주목 하 십시오!

좋은 웹페이지 즐겨찾기