zipファイルをURLからダウンロードし、一旦メモリ上の[]bufferに保存した後、保存するサンプルコード。

二次記憶装置に保存しないので高速だが、大きすぎるファイルには注意すること。

package main

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

// unityのmouse-image.exeが存在しない場合はダウンロードする
func downloadMouseGenerator() error {
	// zipダウンロード
	res, err := http.Get("https://example.com/example.zip")
	if err != nil {
		return err
	}
	defer res.Body.Close()

	// []byte型に変換
	bodyBytes, err := io.ReadAll(res.Body)
	if err != nil {
		return err
	}

	// zip.Readerを作成
	zipReader, err := zip.NewReader(bytes.NewReader(bodyBytes), int64(len(bodyBytes)))
	if err != nil {
		return err
	}

	// zip内のファイル全てを走査し、出力する
	for _, file := range zipReader.File {
		// ファイルのReaderを作成
		fileReader, err := file.Open()
		if err != nil {
			return err
		}
		defer fileReader.Close()

		// 出力パスを決定
		destPath := filepath.Join("output", file.Name)

		// ディレクトリだった場合
		if file.FileInfo().IsDir() {
			os.MkdirAll(destPath, file.Mode())
			continue
		}

		// ファイルの場合は書き込み先を用意
		destination, err := os.OpenFile(destPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, file.Mode())
		if err != nil {
			return err
		}
		defer destination.Close()

		// 書き込み
		_, err = io.Copy(destination, fileReader)
		if err != nil {
			return err
		}
	}
	return nil
}

func main() {
	err := downloadMouseGenerator()
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println("ダウンロード完了")
}