はじめに

表題通り、Golangでファイルをzip化します。

成果物

~/go/src/go_zip$ tree
.
├── files
│   ├── pdf1.pdf
│   ├── pdf2.pdf
│   └── pdf3.pdf
├── go.mod
├── main.go

1 directories, 5 files

1ファイルのみZip化


func main() {
	// ZIPファイルの作成
	zipFile, err := os.Create("output.zip")
	if err != nil {
		fmt.Println(err)
		return
	}
	defer zipFile.Close()

	// ZIPライターの初期化
	zipWriter := zip.NewWriter(zipFile)
	defer zipWriter.Close()

	// PDFファイルをZIPに追加
	if err := addFileToZip("files/pdf1.pdf", zipWriter); err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println("ZIPアーカイブが作成されました")
}

func addFileToZip(filename string, zipWriter *zip.Writer) error {
	// ZIPファイルに新しいファイルエントリを作成
	fileToZip, err := os.Open(filename)
	if err != nil {
		return err
	}
	defer fileToZip.Close()

	// ZIPファイル内のファイルエントリを作成
	fileInfo, err := fileToZip.Stat()
	if err != nil {
		return err
	}

	header, err := zip.FileInfoHeader(fileInfo)
	if err != nil {
		return err
	}

	header.Name = filename
	header.Method = zip.Deflate

	// ZIPファイルにファイルを書き込む
	writer, err := zipWriter.CreateHeader(header)
	if err != nil {
		return err
	}

	_, err = io.Copy(writer, fileToZip)
	return err
}
~/go/src/go_zip$ go run main.go
ZIPアーカイブが作成されました

→これでoutput.zip作成されている事を確認しましょう!

複数ファイルZip化

package main

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

func main() {
	// ZIPファイルの作成
	zipFile, err := os.Create("output_multi.zip")
	if err != nil {
		fmt.Println(err)
		return
	}
	defer zipFile.Close()

	// ZIPライターの初期化
	zipWriter := zip.NewWriter(zipFile)
	defer zipWriter.Close()
	
	// 圧縮したいファイルのリスト
	filesToZip := []string{"files/pdf1.pdf", "files/pdf2.pdf", "files/pdf3.pdf"}

	for _, filename := range filesToZip {
		if err := addFileToZip(filename, zipWriter); err != nil {
			fmt.Println(err)
			return
		}
	}

	fmt.Println("複数のファイルがZIPアーカイブに圧縮されました")
}

func addFileToZip(filename string, zipWriter *zip.Writer) error {
	// ZIPファイルに新しいファイルエントリを作成
	fileToZip, err := os.Open(filename)
	if err != nil {
		return err
	}
	defer fileToZip.Close()

	// ZIPファイル内のファイルエントリを作成
	fileInfo, err := fileToZip.Stat()
	if err != nil {
		return err
	}

	header, err := zip.FileInfoHeader(fileInfo)
	if err != nil {
		return err
	}

	// ZIPファイル内のパスを設定(ファイル名のみ)
	header.Name = filepath.Base(filename)
	header.Method = zip.Deflate

	// ZIPファイルにファイルを書き込む
	writer, err := zipWriter.CreateHeader(header)
	if err != nil {
		return err
	}

	_, err = io.Copy(writer, fileToZip)
	return err
}

→これで実行すると、output_multi.zipが作成され、3つのpdfファイルが作成されています!!