Cloud StorageからダウンロードとアップロードするGo言語コード

『Google Cloud Platform』は非常によく出来たクラウドであり、その中には仮想マシンを提供する『Compute Engine(GCE)』やオブジェクトストレージである『Storage』があります。

これらのサービスはGo言語でも簡単に扱うことが出来て、当記事では『Storage』に保存した画像ファイルを『GCE』にダウンロードし、別ファイルとして『Storage』にアップロードするコードをご紹介します。

もちろん、テキストファイルや他のファイルでも可能です。

コンテンツの転載は固くお断りいたします。

コードの紹介

今回は『yufi.jp』というバケット内にある『image』フォルダの中にある『test1.jpg』というファイルをダウンロードし、同フォルダ内の『test2.jpg』というファイルとしてアップロードしています。


package main

import (
	"bytes"
	"context"
	"log"

	"cloud.google.com/go/storage"
)

func main() {
	ctx := context.Background()

	client, err := storage.NewClient(ctx) // クライアント作成
	if err != nil {
		log.Fatal(err)
	}
	defer client.Close()

	bucket := client.Bucket("yufi.jp") // 接続先バケット

	obj := bucket.Object("image/test1.jpg") // ダウンロードするオブジェクト

	r, err := obj.NewReader(ctx) // ダウンロードするためのリーダー
	if err != nil {
		log.Fatal(err)
	}
	defer r.Close()

	buff := new(bytes.Buffer)
	_, err = buff.ReadFrom(r) // ダウンロード実行
	if err != nil {
		log.Fatal(err)
	}

	outObj := bucket.Object("image/test2.jpg") // アップロード先オブジェクト

	w := outObj.NewWriter(ctx) // アップロードするためのライター
	defer w.Close()

	_, err = buff.WriteTo(w) // アップロード実行
	if err != nil {
		log.Fatal(err)
	}
}


コードの解説

必要なパッケージ


import (
	"bytes"
	"context"
	"log"

	"cloud.google.com/go/storage"
)

『bytes』パッケージは、ダウンロードしたデータを一時保管するバイトバッファーを利用するために使用します。『cloud.google.com/go/storage』は GCP の Storage を扱うためのライブラリです。

以下のコマンドを使用してダウンロードとインストールを行っておいて下さい。


go get cloud.google.com/go/storage

コンテキストを作成して、クライアントも作成する


ctx := context.Background()

client, err := storage.NewClient(ctx) // クライアント作成
if err != nil {
	log.Fatal(err)
}
defer client.Close()

最初に『context.Background』関数を使用してコンテキストを作成し、『storage』パッケージの『NewClient』関数に渡して、Storage に接続するためにクライアントを作成します。

エラーチェックを行い、必要が無くなれば閉じるように『defer client.Close()』としておきます。

使用するバケットとオブジェクトを指定する


bucket := client.Bucket("yufi.jp") // 接続先バケット

obj := bucket.Object("image/test1.jpg") // ダウンロードするオブジェクト

先ほど作成したクライアントの『Bucket』関数に使用するバケット名を渡して、『bucket』を用意します。バケット名は実際に使用するものを指定して下さい。

そして、そのバケットの『Object』関数にダウンロード対象のオブジェクトアドレスを渡します。今回は『image』フォルダ内にある『test1.jpg』というファイルを指定しています。

ダウンロードに必要なリーダーを作成します


r, err := obj.NewReader(ctx) // ダウンロードするためのリーダー
if err != nil {
	log.Fatal(err)
}
defer r.Close()

先ほど用意したオブジェクトの『NewReader』関数にコンテキストを渡してリーダを作成します。このリーダーを使用してダウンロードを行うようになります。

ダウンロードを実行する


buff := new(bytes.Buffer)
_, err = buff.ReadFrom(r) // ダウンロード実行
if err != nil {
	log.Fatal(err)
}

まず、ダウンロードしたデータを保管しておくために『new(bytes.Buffer)』としてバイトバッファーを用意します。

そして、バッファーの『ReadFrom』関数にリーダーを渡してダウンロードします。ダウンロードしたデータはバッファーに入っており、戻り値にはダウンロードしたバイト数とエラーが返ってきます。

アップロードする


outObj := bucket.Object("image/test2.jpg") // アップロード先オブジェクト

w := outObj.NewWriter(ctx) // アップロードするためのライター
defer w.Close()

_, err = buff.WriteTo(w) // アップロード実行
if err != nil {
	log.Fatal(err)
}

アップロードはダウンロードと似たような手順となります。

まずアップロード先オブジェクトを指定し、アップロードするためのライターを作成し、そして『WriteTo』関数にライターを渡してアップロードします。

WriteTo 関数の戻り値はアップロードしたデータのバイト数と、エラー値です。

アップロードする際に指定したオブジェクトが存在しなかった場合、新規にオブジェクトが作成されます。

終わりに

ソースコードを見ていただけると分かりますが、行数は多いですがほとんどがエラー処理や Close 処理です。ダウンロードもアップロードもとてもシンプルですよね。

参考になれば幸いです。