🤐

【Go】ZIPファイルを圧縮・解凍するには?

に公開

はじめに

現在携わっているプロジェクトで、GoでZIPファイルを操作する実装を行う予定です。
先んじてどのように実装できるのか、基本的な圧縮方法と解凍方法を調べました。
各種方法を備忘録的に書いていこうと思います!

環境

  • go version go1.24.0 darwin/arm64
  • macOS Seqoia (バージョン15.3.2)

圧縮

大まかな流れ

  1. ZIPファイルの作成
  2. ZIP用のWirter作成
  3. 対象ファイルの作成
  4. 対象ファイルへの書き込み(今回はテキストファイル)

実装

main.go
func compress(ctx echo.Context) error {
    // ZIPファイルの作成
    output, err := os.Create("output.zip")
    if err != nil {
        log.Fatal(err)
    }
    defer output.Close()
    
    // ZIPライターの作成
    newZipWriter := zip.NewWriter(output)
    defer newZipWriter.Close()
    
    // 対象ファイルの作成
    exampleFile1, err := newZipWriter.Create("example.txt")
    if err != nil {
        log.Fatal(err)
    }
    // 作成したファイルへの書き込み
    exampleFile1.Write([]byte("Hello, World!"))
    
    // 今回は複数のファイルを作成してみる
    exampleFile2, err := newZipWriter.Create("example2.txt")
    if err != nil {
        log.Fatal(err)
    }
    exampleFile2.Write([]byte("Hello, Japan!"))
    
    return nil
}

実行結果

treeコマンドを実行→output.zipが作成されていることがわかる

解凍

流れ

  1. ZIPファイルの読み込み
  2. ZIP内のファイルを開く
  3. 対象ファイルの作成
  4. ファイル内に書き込まれた内容をコピー

実装

main.go
func decompress(ctx echo.Context) error {
    // ZIPファイルの読み込み
    r, err := zip.OpenReader("output.zip")
    if err != nil {
        log.Fatal(err)
    }
    defer r.Close()
    
    // ファイルの作成
    for _, f := range r.File {
        // 一つ一つのファイルを開く
        rc, err := f.Open()
        if err != nil {
            log.Fatal(err)
        }
        defer rc.Close()
    
        // ファイルの作成
        outFile, err := os.Create(f.Name)
        if err != nil {
            log.Fatal(err)
        }
        defer outFile.Close()
    
        // ファイル内に書き込まれた内容をコピー
        _, err = io.Copy(outFile, rc)
        if err != nil {
            log.Fatal(err)
        }
    }
    return nil
}

実行結果

treeコマンドを実行→example1.txtexample2.txtが作成されていることがわかる

まとめ

今回は基本的なZIP圧縮と解凍の実装について見ていきました。
ZIP用の標準ライブラリを使う部分があるものの、要はファイル操作なので、改めてその辺りの知識を深めていく必要があるかと実感しました。
他にも様々な実装方法がありそうなので、色々と見ていきたいと思います!

参考

Discussion