meideru blog

家電メーカーで働いているmeideruのブログです。主に技術系・ガジェット系の話を書いています。

Go言語でZIPファイルを解凍する方法

      2018/11/01

Go言語

最近、サーバサイドのプログラムをGo言語で運用するようになりました。

Go言語でZIPファイルを解凍する必要があり、思いの外、苦戦しました(・_・;

他にも苦労している人がたくさんいるような気がします。

そのため、私の備忘録の意味も込めて、Go言語を用いたZIPファイル解凍のサンプルコードをアップしようと思います。

プログラムについて

ソースコード

以下がソースコードです。

// ZIPファイルを解凍するプログラム

package main

import (
	"archive/zip"
	"io"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
)

func Unzip(src, dest string) error {
	r, err := zip.OpenReader(src)
	if err != nil {
		return err
	}
	defer r.Close()
	
	for _, f := range r.File {
		rc, err := f.Open()
		if err != nil {
			return err
		}
		defer rc.Close()

		if f.FileInfo().IsDir() {
			path := filepath.Join(dest, f.Name)
			os.MkdirAll(path, f.Mode())
		} else {
			buf := make([]byte, f.UncompressedSize)
			_, err = io.ReadFull(rc, buf)
			if err != nil {
				return err
			}

			path := filepath.Join(dest, f.Name)
			err := ioutil.WriteFile(path, buf, f.Mode())
			if err != nil {
				return err
			}
		}
	}

	return nil
}

func main() {
	err := Unzip("./sample.zip", "./")
	if err != nil {
		log.Fatal(err)
	}
}

使い方

Unzip関数の第一引数に解凍したいZIPファイル、第二引数に出力先のディレクトリを渡すだけです。

プログラムの解説

簡単にプログラムの解説も書いておきます。

ZIPファイルの中身を取得

まず、zip.OpenReader関数でZIPファイルの中身を取得します。

zip.OpenReader関数について

この関数は、ZIPファイルの中身を配列で返してきます。

ZIPファイルの中身を1つずつ処理

次に、ZIPファイルの中身を1つずつ処理します。

具体的には

for _, f := range r.File {
// 処理する内容
}

のようにして1つずつ処理します。

 

そして、fがフォーカスしているのがディレクトリであればディレクトリを作成し、ファイルであればファイルを作成します。

// フォーカスしているのがディレクトリのとき
if f.FileInfo().IsDir() {
	// 略
	// フォーカスしているのがファイルのとき
} else {
	// 略
}

 

ファイルの作成方法は、bufというメモリ(スライス)にコピー元のファイルを書き込んで、出力先にファイルを作成して新たに書き込むだけです。

まとめ

以上です。

何か質問がありましたら、気軽にコメントをお願いします_φ( ̄ー ̄ )

 - 技術系