ダメ元エンジニアのお勉強おメモ

ほとんど自分用のメモです。AWS をよく触ります。Web アプリとか作ります。Raspberry Pi も好きです。

GolangでAmazon S3を操作しちゃうサンプル

【概要】

タイトル通り。
あんまりまとめる時間が無いので、超絶ざっくり書いてます。

【環境】

$ sw_vers
ProductName:	Mac OS X
ProductVersion:	10.14.5
BuildVersion:	18F132

$ go version
go version go1.12.5 darwin/amd64

【準備】

$ go get github.com/aws/aws-sdk-go
// @v1.20.16

【処理内容】

下記の順に処理を行う。

  • バケットの存在確認
  • 存在しないならバケットを新規作成
  • バケットの情報を取得・表示
  • オブジェクトの存在確認
  • 存在しないならオブジェクトをアップロード
  • バケット内の全オブジェクトを取得・表示
  • オブジェクトをダウンロード
  • オブジェクトの削除
  • バケットの削除

ソースコード

package main

import (
  "io"
  "log"
  "os"
  "strings"

  "github.com/aws/aws-sdk-go/aws/credentials"

  "github.com/aws/aws-sdk-go/aws"
  "github.com/aws/aws-sdk-go/aws/session"
  "github.com/aws/aws-sdk-go/service/s3"
  "github.com/aws/aws-sdk-go/service/s3/s3manager"
)

const (
  region = "ap-northeast-1"
)

var (
  // Svc is S3 Client
  Svc *s3.S3
  // Sess is AWS Session
  Sess *session.Session
)

func init() {
  creds := credentials.NewSharedCredentials("", "default")
  sess, err := session.NewSession(&aws.Config{
    Credentials: creds,
    Region:      aws.String(region),
  })
  if err != nil {
    log.Fatal(err)
    return
  }

  Svc = s3.New(sess)
  Sess = sess
}

func main() {
  bucketName := "golang-sample-bucket"
  uploadFileName := "upload.txt"
  downloadFileName := "download.txt"

  reader := strings.NewReader("Hello World!")
  writer, err := os.Create(downloadFileName)
  if err != nil {
    log.Fatal(err)
    return
  }
  defer writer.Close()

  if exist := exitstBucket(bucketName); !exist {
    createBucket(bucketName)
  }
  getAllBuckets()

  if exist := existsObject(bucketName, uploadFileName); !exist {
    uploadObject(bucketName, uploadFileName, reader)
  }
  getAllObjects(bucketName)
  downloadObject(writer, bucketName, uploadFileName)

  deleteObject(bucketName, uploadFileName)
  deleteBucket(bucketName)
}

func exitstBucket(bucketName string) bool {
  _, err := Svc.HeadBucket(&s3.HeadBucketInput{
    Bucket: aws.String(bucketName),
  })
  return err == nil
}

func createBucket(bucketName string) {
  _, err := Svc.CreateBucket(&s3.CreateBucketInput{
    Bucket: aws.String(bucketName),
  })
  if err != nil {
    log.Fatal(err)
      return
    }
}

func getAllBuckets() {
  result, err := Svc.ListBuckets(nil)
  if err != nil {
    log.Fatal(err)
      return
  }

  log.Println("Buckets:")
  for _, bucket := range result.Buckets {
    log.Printf("%s created on %s\n",
      aws.StringValue(bucket.Name),
      aws.TimeValue(bucket.CreationDate),
    )
  }
}

func existsObject(bucketName string, key string) bool {
  _, err := Svc.HeadObject(&s3.HeadObjectInput{
    Bucket: aws.String(bucketName),
    Key:    aws.String(key),
  })
  return err == nil
}

func uploadObject(bucketName string, key string, file io.Reader) {
  uploader := s3manager.NewUploader(Sess)
  _, err := uploader.Upload(&s3manager.UploadInput{
    Bucket: aws.String(bucketName),
    Key:    aws.String(key),
    Body:   file,
  })
  if err != nil {
    log.Fatal(err)
    return
  }
}

func getAllObjects(bucktName string) {
  result, err := Svc.ListObjects(&s3.ListObjectsInput{
    Bucket: aws.String(bucktName),
  })
  if err != nil {
    log.Fatal(err)
    return
  }

  log.Println("Objects:")
  for _, obj := range result.Contents {
    log.Println("Name:         ", *obj.Key)
    log.Println("Last modified:", *obj.LastModified)
    log.Println("Size:         ", *obj.Size)
    log.Println("Storage class:", *obj.StorageClass)
  }
}

func downloadObject(file io.WriterAt, bucketName string, key string) {
  download := s3manager.NewDownloader(Sess)
  _, err := download.Download(file,
    &s3.GetObjectInput{
      Bucket: aws.String(bucketName),
      Key:    aws.String(key),
    },
  )
  if err != nil {
    log.Fatal(err)
  }
}

func deleteObject(bucketName string, key string) {
  _, err := Svc.DeleteObject(&s3.DeleteObjectInput{
    Bucket: aws.String(bucketName),
    Key:    aws.String(key),
  })
  if err != nil {
    log.Fatal(err)
    return
  }
}

func deleteBucket(bucketName string) {
  _, err := Svc.DeleteBucket(&s3.DeleteBucketInput{
    Bucket: aws.String(bucketName),
  })
  if err != nil {
    log.Fatal(err)
    return
  }
}