ホームページ  >  記事  >  バックエンド開発  >  golangの圧縮方法

golangの圧縮方法

WBOY
WBOYオリジナル
2023-05-22 09:47:062177ブラウズ

golang は、比較的強力なコード実行機能を備えた非常に人気のある高性能プログラミング言語であり、その標準ライブラリには、さまざまなファイル圧縮形式を処理するためのメソッドも多数含まれています。この記事では、golang 圧縮方法の使用方法を紹介します。

まず、golang標準ライブラリの圧縮処理関連パッケージである「compress」パッケージと「archive」パッケージを導入する必要があります。ただし、どちらを選択するかは圧縮形式によって異なります。

  1. gzip 圧縮

golang での gzip 圧縮の方法でも、標準ライブラリの「compress/gzip」パッケージが使用されます。

ここでは圧縮の例として文字列を取り上げます:

package main

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

func main() {
    str := "golang gzip test"
    var buf bytes.Buffer
    z := gzip.NewWriter(&buf)
    _, err := z.Write([]byte(str))
    if err != nil {
        panic(err)
    }
    err = z.Close()
    if err != nil {
        panic(err)
    }
    fmt.Println("gzip:", buf.String())
}

このコードでは、最初にバッファ キャッシュが作成され、次に gzip.Write オブジェクトが作成され、バッファが に渡されます。このオブジェクト。次に、圧縮する必要がある文字列をこのオブジェクトに書き込み、最後にライター オブジェクトを閉じます。

出力結果は次のようになります: gzip: �▒H-IM0189WVnV-I�HI�J-.�V�R,Q�P.�-NMV-.WVN�O�,�R�� S �Q�L�K�_(�з)_/�

  1. zlib 圧縮

zlib は、Lempel-Ziv アルゴリズムを使用する可逆データ圧縮形式であり、ハファムコーディング。比較的高い圧縮率と比較的速い圧縮速度を備えており、特定のデータ送信およびストレージのシナリオで使用できます。

golang での zlib 圧縮の方法でも、標準ライブラリの「compress/zlib」パッケージが使用されます。

ここでは圧縮の例として文字列を取り上げます:

package main

import (
    "bytes"
    "compress/zlib"
    "fmt"
)

func main() {
    str := "golang zlib test"
    var buf bytes.Buffer
    w := zlib.NewWriter(&buf)
    _, err := w.Write([]byte(str))
    if err != nil {
        panic(err)
    }
    err = w.Close()
    if err != nil {
        panic(err)
    }
    fmt.Println("zlib:", buf.String())
}

このコードでは、最初にバッファ キャッシュが作成され、次に zlib.Write オブジェクトが作成され、バッファが に渡されます。このオブジェクト。次に、圧縮する必要がある文字列をこのオブジェクトに書き込み、最後にライター オブジェクトを閉じます。

出力結果は次のとおりです: zlib: x�� ��J-.N��(,�QP.I,�M-V-.Q��

  1. tar 圧縮

tar は、複数のファイルまたはディレクトリを 1 つのファイルにパッケージ化するためによく使用されるアーカイブ ファイル形式です。golang で tar 圧縮を実行するには、標準ライブラリの "archive/tar" パッケージを使用できます。

ここではディレクトリの tar 圧縮を例にします:

package main

import (
    "archive/tar"
    "fmt"
    "io"
    "os"
)

func tarPath(dst, src string) error {
    info, err := os.Stat(src)
    if err != nil {
        return err 
    }

    // 如果源目录是一个文件,直接对这个文件进行压缩
    if !info.IsDir() {
        srcFile, err := os.Open(src)
        if err != nil {
            return err
        }
        defer srcFile.Close()

        dstFile, err := os.Create(dst + ".tar")
        if err != nil {
            return err
        }
        defer dstFile.Close()

        tarWriter := tar.NewWriter(dstFile)
        defer tarWriter.Close()

        hdr := &tar.Header {
            Name: src,
            Mode: int64(info.Mode()),
            Size: info.Size(),
        }

        if err := tarWriter.WriteHeader(hdr); err != nil {
            return err 
        }

        if _, err := io.Copy(tarWriter, srcFile); err != nil {
            return err
        }

        fmt.Println("tar file created:", dst+".tar")
        return nil 
    }

    // 如果源目录是一个文件夹,先遍历源目录
    files, err := os.ReadDir(src)
    if err != nil {
        return err 
    }

    for _, file := range files {
        fileName := file.Name()

        // 这里需要再次判断是否是一个目录
        if file.IsDir() {
            fmt.Println("skipping directory:", fileName)
            continue
        }

        srcFile, err := os.Open(filepath.Join(src, fileName))
        if err != nil {
            return err
        }
        defer srcFile.Close()

        dstFile, err := os.Create(filepath.Join(dst, fileName) + ".tar")
        if err != nil {
            return err
        }
        defer dstFile.Close()

        tarWriter := tar.NewWriter(dstFile)
        defer tarWriter.Close()

        hdr := &tar.Header {
            Name: fileName,
            Mode: int64(file.Mode()),
            Size: file.Size(),
        }

        if err := tarWriter.WriteHeader(hdr); err != nil {
            return err 
        }

        if _, err := io.Copy(tarWriter, srcFile); err != nil {
            return err
        }

        fmt.Println("tar file created:", filepath.Join(dst, fileName)+".tar")
    }

    return nil 
}

func main() {
    srcPath := "./testdir"
    dstPath := "./"

    err := tarPath(dstPath, srcPath)
    if err != nil {
        fmt.Println(err)
    }
}

このコードでは、最初にソース パスが判断され、ファイルの場合は直接圧縮されて保存されます。

  1. zip 圧縮

zip はい アーカイブ ファイル形式, これは通常、一連のファイルまたはディレクトリを 1 つのファイルにパッケージ化し、これらのファイルを圧縮するために使用されます。golang で zip 圧縮を実行するには、標準ライブラリ パッケージの「archive/zip」を使用できます。ここでは例として 2 つのファイルの zip 圧縮を取り上げます:

package main

import (
    "archive/zip"
    "fmt"
    "io"
    "os"
)

func zipFiles(dst string, files []string) error {
    newZipFile, err := os.Create(dst + ".zip")
    if err != nil {
        return err
    }
    defer newZipFile.Close()
    zipWriter := zip.NewWriter(newZipFile)
    defer zipWriter.Close()

    for _, file := range files {
        srcFile, err := os.Open(file)
        if err != nil {
            return err
        }
        defer srcFile.Close()

        info, _ := srcFile.Stat()

        header, err := zip.FileInfoHeader(info)
        if err != nil {
            return err
        }
        header.Name = file
        header.Method = zip.Deflate

        writer, err := zipWriter.CreateHeader(header)
        if err != nil {
            return err
        }
        if _, err := io.Copy(writer, srcFile); err != nil {
            return err
        }
    }

    fmt.Println("zip file created:", dst+".zip")
    return nil 
}

func main() {
    files := []string{"test.txt", "test1.txt"}
    dstPath := "./"

    err := zipFiles(dstPath, files)
    if err != nil {
        fmt.Println(err)
    }
}

このコードでは、主に圧縮が必要なファイルのリストを走査し、それらを 1 つずつ圧縮パッケージに追加します。

概要

golang には、さまざまな圧縮形式に対応する処理ライブラリがあり、ファイル圧縮処理プロセスが大幅に容易になります。ここでは、一般的なものをいくつか紹介します。ファイル圧縮方法の処理方法。

以上がgolangの圧縮方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
前の記事:golangデプロイXP次の記事:golangデプロイXP