Web開発ログ | エンジニアに役立つ情報 | 開発の中での気づきを発信

高卒Devlog

【aws-sdk-go】GolangでS3にZipファイルを保存してみた

thumbnail

こんにちは! RYOTAです!

当記事をご覧くださりありがとうございます!

Golangを使ってS3へのアクセスを行ってみたので簡単に実装方法をまとめていきます!

はじめに

業務でGolangを使ってS3バケットへのアクセスを行い、データの取得と保存の処理を行なったので具体的な実装方法を解説していきます。
S3オブジェクトのアクセスは割と頻度が高い実装になると思うので、是非こちらの記事を参考にしていただければと思います。
今回は下記のライブラリを使用します。

  • aws/aws-sdk-go

GitHub - aws/aws-sdk-go: AWS SDK for the Go programming language. AWS SDK for the Go programming language. Contribute to aws/aws-sdk-go development by creating an account on GitHub. GitHub
それでは早速やっていきましょう!

実装方法

AWS SDKをインストール

$ go get -u github.com/aws/aws-sdk-go

インポート

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

S3セッションの初期化

session, err := session.NewSessionWithOptions(session.Options{
	Config: aws.Config{Region: aws.String("ap-northeast-1")},
})
if err != nil {
	panic(err)
}

送信ファイルを指定(ファイルオープン)

前回の記事で作成したZipファイルをS3に送ることにします。
Zip送信でハマったポイントがあるのですが、そちらは別の記事にて。

upFile, err := os.Open("./csv/test.zip")
if err != nil {
	return err
}
defer upFile.Close()

ファイルサイズの取得

バッファーを設定しファイルの書き込み領域を確保します。

upFileInfo, err := upFile.Stat()
if err != nil {
	fmt.Println(err)
}

var fileSize int64 = upFileInfo.Size()
fileBuffer := make([]byte, fileSize)
upFile.Read(fileBuffer)

S3へアップロード

事前にS3でtest-bucketというバケットを作成しておき、そちらに対象のZipをアップロードします。
Bodyには前のステップで設定したfileBufferを渡してあげます。

_, err = s3.New(session).PutObject(&s3.PutObjectInput{
	Bucket:               aws.String("test-bucket"),
	Key:                  aws.String("test.zip"),
	ACL:                  aws.String("private"),
	Body:                 bytes.NewReader(fileBuffer),
	ContentLength:        aws.Int64(fileSize),
	ContentType:          aws.String("application/zip"),
	ContentDisposition:   aws.String("attachment"),
	ServerSideEncryption: aws.String("AES256"),
})

これを実行してあげると無事にS3に対象のファイルの送信が完了です!
まとめるとこんな感じになります。

package s3

import (
	"bytes"
	"fmt"
	"os"

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

func UploadS3() error {
	// S3セッション初期化
	session, err := session.NewSessionWithOptions(session.Options{
		Config: aws.Config{Region: aws.String("ap-northeast-1")},
	})
	if err != nil {
		panic(err)
	}

	// 送信ファイルを指定
	upFile, err := os.Open("./csv/test.zip")
	if err != nil {
		return err
	}
	defer upFile.Close()

	// バッファーの設定
	upFileInfo, err := upFile.Stat()
	if err != nil {
		fmt.Println(err)
	}

	// ファイルサイズの取得
	var fileSize int64 = upFileInfo.Size()
	fileBuffer := make([]byte, fileSize)
	upFile.Read(fileBuffer)

	// S3 アップロード
	_, err = s3.New(session).PutObject(&s3.PutObjectInput{
		Bucket:               aws.String("test-bucket"),
		Key:                  aws.String("test.zip"),
		ACL:                  aws.String("private"),
		Body:                 bytes.NewReader(fileBuffer),
		ContentLength:        aws.Int64(fileSize),
		ContentType:          aws.String("application/zip"),
		ContentDisposition:   aws.String("attachment"),
		ServerSideEncryption: aws.String("AES256"),
	})
	return err
}

さいごに

今回はGolangで生成したZipをS3に保存してみました!
送信自体は簡単でしたがバッファーの概念が一癖あったのと、Zipを送る段階でファイルサイズが異なるサイズになるという問題が発生しそこそこ苦戦しました。
S3にそれっぽいファイルは送れているが開こうとしてもZipとして認識しないという問題があったので、そちらは別の記事で紹介しようと思います!
最後までご覧くださりありがとうございます!