1

私は Goamz パッケージを使用しておりbucket.Multi、HTTP GET 応答を S3 にストリーミングするための助けを借りることができます。

チャンクされた HTTP 経由で 2 GB 以上のファイルをダウンロードし、S3 バケットに直接ストリーミングしたいと考えています。

resp.Bodyの実装をs3.ReaderAtSeekerに渡すことができるように、何かでラップする必要があるようですmulti.PutAll

// set up s3
auth, _ := aws.EnvAuth()
s3Con := s3.New(auth, aws.USEast)
bucket := s3Con.Bucket("bucket-name")

// make http request to URL
resp, err := http.Get(export_url)
if err != nil {
    fmt.Printf("Get error %v\n", err)
    return
}

defer resp.Body.Close()

// set up multi-part 
multi, err := bucket.InitMulti(s3Path, "text/plain", s3.Private, s3.Options{})
if err != nil {
    fmt.Printf("InitMulti error %v\n", err)
    return
}

// Need struct that implements: s3.ReaderAtSeeker
// type ReaderAtSeeker interface {
//  io.ReaderAt
//  io.ReadSeeker
// }

rs := // Question: what can i wrap `resp.Body` in?

parts, err := multi.PutAll(rs, 5120)
if err != nil {
    fmt.Printf("PutAll error %v\n", err)
    return
}

err = multi.Complete(parts)
if err != nil {
    fmt.Printf("Complete error %v\n", err)
    return
}

現在、プログラムを実行しようとすると、次の (予想される) エラーが発生します。

./main.go:50: cannot use resp.Body (type io.ReadCloser) as type s3.ReaderAtSeeker in argument to multi.PutAll:
    io.ReadCloser does not implement s3.ReaderAtSeeker (missing ReadAt method)
4

2 に答える 2

1

S3 api にアクセスするために使用しているパッケージを指定していませんが、これだと思います https://github.com/mitchellh/goamz/ .

ファイルのサイズが大きいため、可能な解決策はmulti.PutPartを使用することです。これにより、 multi.PutAllよりも詳細に制御できます。標準ライブラリのReaderを使用すると、アプローチは次のようになります。

  1. 応答ヘッダーから Content-Length を取得します
  2. Content-Length と partSize に基づいて、必要なパーツの数を取得します
  3. 部分の番号をループし、response.Body から []byte を読み取り、bytes.Reader に変換し、multi.PutPart を呼び出します。
  4. multi.ListPartsからパーツを取得する
  5. コールマルチ。パーツ付きでコンプリート。

私は S3 にアクセスできないので、仮説をテストすることはできませんが、上記の内容は、まだ検討していない場合は検討する価値があります。

于 2014-12-27T06:07:53.247 に答える