Block 단위 압축 및 해제


압축 데이터는 한개 이상의 Block으로 구성됩니다. Block는 동일한 압축 레벨과 압축 방법을 사용합니다. deflateParams 함수로 압축 레벨과 압축 방법을 지정하면 새로운 Block이 만들어집니다. deflateParams 함수는 기존 avail_in에 0이 아니면 기존 방식대로 데이터를 압축하고, 마지막에 새로운 Block 헤더를 추가합니다.

압축을 푸는 과정은 inflate(&stream, Z_BLOCK)를 사용합니다. 만약 Block에 있는 데이터를 구분할 필요가 없다면 inflate(&stream, Z_NO_FLUSH)로 읽어가면 됩니다. 하지만 Block 별 데이터를 구분해서 읽고 싶다면 Z_BLOCK으로 읽어가야 합니다. 읽어진 정보는 data_type 변수로 상태 정보를 체크할 수 있습니다.

//stream.data_type
// 첫번째 비트가 1이면 block를 읽었음 의미
// 두번째 비트가 1이면 block를 읽고 있는 중..
// valil_in ==0 이고 두번째 비트가 1이면 모든 데이터를 읽어드림.

// Sample4_Block.cpp : Defines the entry point for the console application.
//

#include  "stdafx.h"

#include  <LibZ/zlib.h>
#include  <iostream>

int _tmain(int argc, _TCHAR* argv[])
{
   Bytef m1[]="test1";
   Bytef m2[]="test2";

   const  int BUF=4096;

   //압축된  데이터와  길이
   Bytef deflate_data[BUF];
   int deflate_size(0);

   //해제된  데이터와  길이
   Bytef inflate_data[BUF];
   int inflate_size(0);

   //압축  코딩
   do{
      z_stream stream;
       stream.zalloc = Z_NULL;
       stream.zfree = Z_NULL;
       stream.opaque = Z_NULL;
      int ret = deflateInit(&stream,Z_DEFAULT_COMPRESSION);//블락 1
      if( Z_OK != ret) break;

       stream.next_out = deflate_data;
       stream.avail_out = BUF;

       stream.avail_in =0;//
       deflateParams(&stream,Z_BEST_COMPRESSION,Z_HUFFMAN_ONLY);//블락 2

       stream.avail_in = strlen((const  char*)m1);
       stream.next_in = m1;
      do {
          deflate(&stream, Z_NO_FLUSH);
      } while( 0!= stream.avail_in);

       deflateParams(&stream, Z_BEST_SPEED,Z_RLE);//블락 3
       stream.avail_in = strlen( (const  char*) m2);
       stream.next_in = m2;
      do {
          deflate(&stream, Z_NO_FLUSH);
      } while( 0!= stream.avail_in);

       deflate(&stream, Z_FINISH);//블락 4
       deflate_size = BUF- stream.avail_out;
       std::cout<<"Deflate Size:"<<deflate_size<<std::endl;

       deflateEnd(&stream);

   }while(false);

   //해제하기
   do{
      z_stream stream;
       stream.zalloc = Z_NULL;
       stream.zfree = Z_NULL;
       stream.opaque = Z_NULL;
      int ret = inflateInit(&stream);
      if (Z_OK != ret) break;

       stream.next_out = inflate_data;
       stream.avail_out= BUF;

       stream.next_in = deflate_data;
       stream.avail_in = deflate_size;

      do{
          ret = inflate(&stream,Z_BLOCK);
          inflate_size = BUF-stream.avail_out;
          inflate_data[inflate_size]=NULL;
          std::cout<<"////////////////////////"<<std::endl;
          std::cout<<"Block Readed OK:"<< ( ( stream.data_type & 128 )?1:0 )<<std::endl;
          std::cout<<"Block Reading:"<< ( ( stream.data_type & 64 )?1:0 )<<std::endl;
          std::cout<<"Return:"<< ret<<std::endl;
          std::cout<<"avail_in:"<<stream.avail_in<<std::endl;
          std::cout<<"NOW Data:"<<(const  char*)inflate_data<<std::endl;
          std::cout<<"NOW Data Len:"<<inflate_size<<std::endl;
      }while(Z_STREAM_END !=ret);

       inflateEnd(&stream);

   }while( false);


    system("pause");

   return 0;
}

- 목록:

13 thoughts on “gz 파일 사용하기

  1. 안녕하세요 좋은 영상과 글을 잘 봤습니다.
    글에 보면 “입력 버퍼와 출력 버퍼를 고정으로한 압축 함수”에 대해서 어떤 함수를 봐야 하는지 알수 있을까요?
    좋은 글 감사드리며, 오래된 글에 문의를 남깁니다.
    감사합니다.

  2. 동영상 잘 보았습니다. 궁금한것이 있는데요, Z_SYNC_FLUSH 를 사용할 경우에, 만약 next_out buffer 크기가 압축한 data 를 담기에 충분하지 않는다면, 어떻게 해야 하는지요?

    • Z_SYNC_FLUSH는 쓰고 있는 비트를 모두 바이트 단위로 쓰라는 옵션임으로 일반적인 쓰기 과정에서 발생한 에러 코드를 반환하게 되어 있습니다. [Deflate 샘플] 동영상을 참고하세요.

  3. C로 압축하고 c#으로 압축을 푸는 방법이 있을까요?
    텍스트 파일을 작성시

    gzwritre(파일 포인터, 2019, sizeof(int));
    gzwritre(파일 포인터, 09, sizeof(int));
    gzwritre(파일 포인터, 17, sizeof(int));

    gzwritre(파일 포인터, 0.1, sizeof(float)); 결과값
    gzwritre(파일 포인터, 0.2, sizeof(float));
    gzwritre(파일 포인터, 0.3, sizeof(float));

    gzwritre(파일 포인터, 100.0, sizeof(float));

    이렇게 텍스트 파일을 저장(압축)했는데 C#에서 이 파일을 읽어서

    연 / 월 / 일 을 정수 변수에
    결과값을 실수배열에 저장하고 싶습니다.

  4. 분할 압축파일일 경우 zilb로 압축 해제가 가능 한가요?
    아니면 다른 라이브러리를 사용해야 할까요 ?

    • 별도로 지원하는 함수는 없지만 그냥 저장하는 과정에서 파일만 나눠 저장하는 것이 아닐지요.

  5. 안녕하세요
    c++에서 zlib uncompress로 .emf image 파일을 압축해제 하려고 합니다.
    그런데 손상된 파일이을 대상으로 진행할 경우 Z_DATA_ERROR을 반환하면서 자동종료됩니다.
    압축된 파일이 Z_DATA_ERROR를 반환하면(손상된 파일이면) 빈 .emf image 파일로 압축해제 되도록 하려면 어떻게 해야할까요?

  6. 리눅스에서 C언어를 사용해서 zlib으로 위와 같이 폴더(디렉토리)를 압축할수있나요?

Leave a Reply to hinata Cancel reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>