2022.09.22  

【Go】S3から取得したcsv.gzファイルを展開して読み込む

Go,  AWS    

S3から取得したcsv.gzファイルを展開して読み込む処理のメモ書きです。

package main

import (
    "compress/gzip"
    "context"
    "encoding/csv"
    "fmt"
    "io"

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

type (
    S3Client interface {
        GetObject(ctx context.Context, key string) (*s3.GetObjectOutput, error)
    }

    s3Config struct {
        AwsDefaultRegion string
        EndPoint         string
        BucketName       string
    }

    s3client struct {
        clientCfg *s3Config
        sdkCfg    aws.Config
    }
)

func main() {

    cfg := s3Config{
        AwsDefaultRegion: "ap-northeast-1",
        EndPoint:         "http://localhost:8080",
        BucketName:       "hogeBucket",
    }

    // S3クライアントの作成
    c := NewS3Client(&cfg)

    // S3からCSVファイルを取得
    file, err := c.GetObject(context.Background(), "testDir/hoge.csv")
    if err != nil {
        fmt.Println("エラー")
        return
    }

    // gzipファイルを展開する
    f, err := gzip.NewReader(file.Body)
    if err != nil {
        fmt.Println("エラー")
        return
    }
    defer func() {
        _ = f.Close()
    }()

    // 展開したgzipファイルをCSVファイルとして読み込む
    r := csv.NewReader(f)

    // csvファイルの中身を読み込
    for {
        record, err := r.Read()
        if err == io.EOF {
            break
        }
        if err != nil {
            fmt.Println("エラー")
        }
        fmt.Println(record)
    }
}

// S3クライアントの作成
func NewS3Client(cfg *s3Config) S3Client {
    loadOptions := []func(*config.LoadOptions) error{config.WithRegion(cfg.AwsDefaultRegion)}

    if cfg.EndPoint != "" {
        endpoint := aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
            return aws.Endpoint{
                URL: cfg.EndPoint,
            }, nil
        })
        loadOptions = append(loadOptions, config.WithEndpointResolverWithOptions(endpoint))
    }

    sdkCfg, err := config.LoadDefaultConfig(context.TODO(), loadOptions...)
    if err != nil {
        panic(err)
    }
    return &s3client{cfg, sdkCfg}
}

// S3からファイルを取得する関数
func (c *s3client) GetObject(ctx context.Context, key string) (*s3.GetObjectOutput, error) {
    api := s3.NewFromConfig(c.sdkCfg, func(options *s3.Options) {
        options.UsePathStyle = true
    })

    return api.GetObject(ctx, &s3.GetObjectInput{
        Bucket: aws.String(c.clientCfg.BucketName),
        Key:    aws.String(key),
    })
}

コメント
現在コメントはありません。
コメントする
コメント入力

名前 (※ 必須)

メールアドレス (※ 必須 画面には表示されません)

送信