무지개곰
article thumbnail

데이터 압축은 웹 서버, 파일 저장 및 네트워크 통신과 같은 다양한 상황에서 중요한 역할을 합니다. Go 언어에서는 'compress/gzip' 패키지를 통해 Gzip 압축을 쉽게 구현할 수 있습니다. 이번 글에서 'compress/gzip' 패키지에 대하여 기록하겠습니다.

목차

Gzip이란?

compress/gzip 패키지

compress/gzip 사용 예시


Gzip이란?

Gzip은 파일 및 데이터 압축 및 해제를 위한 파일 형식 및 관련된 알고리즘을 지칭하는 용어입니다.

특징

1. 높은 압축률 : 'Gzip'은 데이터를 효율적으로 압축하여 파일 또는 데이터 스트림의 크기를 줄입니다. 이는 디스크 공간을 절약하고 데이터 전송 시 대역폭을 절약하는 데 도움이 됩니다.

2. 비손실 압축 : 'Gzip'은 비손실 압축 알고리즘 중 하나이므로 압축된 데이터를 정확하게 복원할 수 있습니다. 이는 파일이나 데이터의 무결성을 유지하는 데 중요합니다.

3. 다양한 운영 체제 호환 : 'Gzip'은 여러 운영 체제에서 사용 가능하며, 다양한 프로그램 및 라이브러리에서 지원됩니다. 따라서 다른 운영 체제 간에 Gzip으로 압축된 데이터를 공유할 수 있습니다.

4. 압축 형식 : 'Gzip'으로 압축된 파일은 '.gz' 확장자를 가집니다. 예를 들어 'example.txt'파일을 Gzip으로 압축한 경우 'example.txt.gz'파일이 생성됩니다.


compress/gzip 패키지

Go 언어에서 gzip 압축을 쉽게 구현하기 위하여 'compress/gzip' 패키지를 사용합니다. HTTP 응답 압축을 통해 웹 페이지의 로딩 속도를 향상 시키고 대역폭을 절약할 수 있다고 합니다.

핵심 메서드

'compress/gzip'을 사용하는 이유는 데이터를 압축하고 압축을 풀기 위하여 사용합니다. 이와 관련된 핵심 메서드는 아래의 두 개의 메서드입니다.

gzip.NewWriter : Gzip압축을 수행하는 쓰기 인터페이스를 생성하기 위하여 사용하는 메서드입니다.

gzip.NewReader : Gzip압축 해제를 위한 리더 인터페이스를 생성하기 위하여 사용하는 메서드입니다.

예시 코드

샘플 코드는 아래의 github에도 올려두었습니다.

https://github.com/rainbow96bear/golang_practice/blob/master/Gzip/Gzip.go

package main

import (
	"bytes"
	"compress/gzip"
	"fmt"
	"io"
)

func main(){
	sampleData := "Hi This is Rainbowbear World."

	// string을 byte 데이터로 변환
	Data := []byte(sampleData)

	// 데이터 압축
	compresssedData, err := compressData(Data)
	if err != nil{
		fmt.Println("Compress fail", err)
	}
	fmt.Println("압축 된 데이터 :", string(compresssedData))

	// 압축된 데이터 풀기
	decompressedData, err := decompressData(compresssedData)
	if err != nil {
		fmt.Println("decompress fail", err)
		return
	}
	fmt.Println("압축이 풀린 데이터 :", string(decompressedData))

	fmt.Println("원본 데이터 :",sampleData)
}

func compressData(data []byte) ([]byte, error){
	buf := new(bytes.Buffer)
	writer := gzip.NewWriter(buf)
	_, err := writer.Write(data)

	if err != nil {
		return nil, err
	}
	writer.Close()
	return buf.Bytes(), nil
}

func decompressData(data []byte) ([]byte, error){
	r, err := gzip.NewReader(bytes.NewReader(data))

	if err != nil {
		return nil, err
	}
	defer r.Close()

	originData, err := io.ReadAll(r)
	if err != nil {
		return nil, err
	}
	return originData, nil
}

예시 코드는 생각보다 간단합니다. 압축을 하는 'compressData', 압축을 푸는 'decompressData'를 만들었습니다.

compressData : 압축할 데이터를 매개변수로 받고 데이터를 압축하여 작성하는 writer인터페이스를 생성하여 'Write'메서드를 사용하여 데이터를 압축합니다.

decompressData : 압축을 풀어야 하는  데이터를 매개변수로 받고 압축된 데이터를 읽기 위하여 bytes.NewReader를 이용하여 byte 정보를 읽고 값을 gzip의 Reader에게 전달합니다.

 

압축과 해제된 값을 출력하면 아래와 같습니다.

압축된 데이터의 경우 읽을 수 없는 문자로 변환된 것을 확인할 수 있습니다. 또한 문자열로 읽을 수 없는 데이터를 압축을 풀었을 경우 다시 읽을 수 있는 것을 확인할 수 있습니다.


compress/gzip 사용 예시

compress/gzip 패키지는 다양한 상황에서 사용될 수 있다고 합니다. 그중 3가지의 상황에 따른 간단한 예시를 기록하겠습니다.

웹 서버 응답 압축

웹 서버에서 HTTP 응답 압축을 통해 웹 페이지의 로딩 속도를 향상 시키고 대역폭을 절약하기 위하여 Gzip으로 응답 데이터를 압축할 수 있습니다.

func handler(w http.ResponseWriter, r *http.Request) {
    // handler 작업
    
    w.Header().Set("Contest-Encoding", "gzip")
    writer := gzip.NewWriter(w)
    writer.Write(responseData)
    writer.Close
}

'http.ResponseWriter''Header'를 'gzip'으로 변경 후 writer를 생성하고  handler에서 생성한 responseData를 압축하여 보내는 방법을 사용할 수 있습니다.

네트워크 통신

소켓 연결 등 네트워크 통신 중에 데이터를 Gzip으로 압축하여 전송할 수 있습니다.

func sendData(conn net.Conn, data []byte) err {
    writer := gzip.NewWriter(conn)
    _, err := writer.Write(data)
    if err != nil {
        return err
    }
    writer.Close()
    
    return nil
}

파일 압축

알집으로 파일을 압축하면 zip이 생성되는 것처럼 Gzip 형식으로 압축할 수 있습니다. 이 방법을 통하여 디스크 공간을 절약할 수 있습니다.

func compressFile(inputFile, outputFile string) error {
    data, err := os.ReadFile(inputFile)
    if err != nil {
        return err
    }
    
    buf := new(bytes.Buffer)
    writer := gzip.NewWriter(buf)
    _, err = writer.Write(data)
    if err != {
        return err
    }
    writer.Close()
    
    err = os .WriteFile(output.File, buf.Bytes(), 6044)
    if err != nil {
        return err
    }
    
    return nil
}

'os'패키지의 'ReadFile'을 사용하여 파일을 읽어오고 압축합니다. 압축된 데이터를 'os'패키지의 'WriteFile'를 사용하여 압축된 파일을 생성합니다.

위 함수의 매개변수인 'inputFile'과 'outputFile'은 읽어올 파일과 작성할 파일의 경로입니다.

 

profile

무지개곰

@무지개곰

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!