GoでGCSのファイルのアップロード&移動


GCSにファイルをアップロードをしたり、移動したりするのをGolangでやってみました。
レポジトリはこちらに置いてあります。dockerコンテナを立てて試すことができます。
https://github.com/greenteabiscuit/gcs-golang

前提条件

  • GCPのアカウントがある
  • Dockerのダウンロードができている
  • GCSの閲覧、編集権限のある鍵ファイルをダウンロードできている

やること

  1. 空のファイルsample.txtをGCSにアップロードしてみる
  2. GCSにアップロードできたsample.txtを別のディレクトリに移動する

1. アップロードしてみる

main.go
package main

import (
    "context"
    "io"
    "log"
    "os"

    "cloud.google.com/go/storage"
    "google.golang.org/api/option"
)

func main() {
    credentialFilePath := "./key.json" // key.jsonはサービスアカウントを作成してゲットする

    // クライアントを作成する
    ctx := context.Background()
    client, err := storage.NewClient(ctx, option.WithCredentialsFile(credentialFilePath))
    if err != nil {
        log.Fatal(err)
    }

    // GCSオブジェクトを書き込む空のsample.txtファイルをローカルで作成
    f, err := os.Create("sample.txt")
    if err != nil {
        log.Fatal(err)
    }

    // オブジェクトのReaderを作成
    bucketName := "experimental-bucket-tt"   // e.g. example-bucket
    objectPath := "sample-object/sample.txt" // e.g. foo/var/sample.txt

    writer := client.Bucket(bucketName).Object(objectPath).NewWriter(ctx)
    if _, err := io.Copy(writer, f); err != nil {
        panic(err)
    }

    if err := writer.Close(); err != nil {
        panic(err)
    }

    log.Println("done")
}

Dockerで仮想環境を立てて、その中で実行してみます。
モジュールをダウンロードするのを忘れずに。

$ docker-compose up

// In different tab
$ docker exec -it containername bash

//以下のモジュールをダウンロードする必要がある。

/go/src# go mod init example.com/gcs/write

/go/src# go get -u cloud.google.com/go/storage

うまくいけばdoneと出るはずです。

/go/src# go run main.go
2020/12/29 01:36:24 done

バケットのルートディレクトリにてsample.txtがアップロードされているはずです。

2. ファイルをGCS内で移動する。

残念ながらただの移動する関数はないので、目的のフォルダにコピーし、元のフォルダにあるファイルを消す、という順序になります。
また、途中のフォルダは作成されていない場合はGCS側(?)が作成してくれます。
今回はdestination-folder/30というテキトーな名前のフォルダに移します。

main.go
package main

import (
    "context"
    "io"
    "log"
    "os"

    "cloud.google.com/go/storage"
    "google.golang.org/api/option"
)

func main() {
    credentialFilePath := "./key.json" // key.jsonはサービスアカウントを作成してゲットする

    // クライアントを作成する
    ctx := context.Background()
    client, err := storage.NewClient(ctx, option.WithCredentialsFile(credentialFilePath))
    if err != nil {
        log.Fatal(err)
    }

    // GCSオブジェクトを書き込むファイルの作成
    f, err := os.Create("sample.txt")
    if err != nil {
        log.Fatal(err)
    }

    // ......................
    // オブジェクトのアップロード
    // ......................
    bucketName := "experimental-bucket-tt"   // e.g. example-bucket
    objectPath := "sample-object/sample.txt" // e.g. foo/var/sample.txt

    uploadWriter := client.Bucket(bucketName).Object(objectPath).NewWriter(ctx)
    if _, err := io.Copy(uploadWriter, f); err != nil {
        panic(err)
    }

    if err := uploadWriter.Close(); err != nil {
        panic(err)
    }
    log.Println("create file: done")

    // ......................
    // オブジェクトの移動
    // ......................
    dstObjectPath := "destination-folder/30/sample.txt"
    src := client.Bucket(bucketName).Object(objectPath)
    dst := client.Bucket(bucketName).Object(dstObjectPath)
    if _, err := dst.CopierFrom(src).Run(ctx); err != nil {
        panic(err)
    }
    if err := src.Delete(ctx); err != nil {
        panic(err)
    }
    log.Println("move file: done")
}

これでファイルを作成してアップロード、そしてアップロードしたファイルの移動に成功するはずです。

/go/src# go run main.go
2020/12/29 10:05:55 create file: done
2020/12/29 10:05:55 move file: done

destination-folder/30フォルダに移動されているはずです。

参考

Reading and Writing to Google Cloud Storage
Go言語(golang)でGoogle Cloud Storageへファイルをアップロードする