如何使用 Go 跟踪分段上传到 s3 的进度?

fro*_*wns 5 amazon-s3 go amazon-web-services goamz

我正在尝试使用 Mitchell Hashimoto 的 goamz fork 提供的 PutPart 方法。可悲的是,每次我拿回一部分并检查大小时,似乎都认为它是整个文件的大小,而不仅仅是一个块的大小。

例如

当上传 15m 文件时我希望看到

Uploading...
Processing 1 part of 3 and uploaded 5242880.0 bytes.
 Processing 2 part of 3 and uploaded 5242880.0 bytes.
 Processing 3 part of 3 and uploaded 5242880.0 bytes.
Run Code Online (Sandbox Code Playgroud)

相反,我看到:

Uploading...
Processing 1 part of 3 and uploaded 15728640 bytes.
 Processing 2 part of 3 and uploaded 15728640 bytes.
 Processing 3 part of 3 and uploaded 15728640 bytes.
Run Code Online (Sandbox Code Playgroud)

这是由于 file.Read(partBuffer) 的问题造成的吗?任何帮助将非常感激。

我在 Mac 上使用 go 1.5.1。

Uploading...
Processing 1 part of 3 and uploaded 5242880.0 bytes.
 Processing 2 part of 3 and uploaded 5242880.0 bytes.
 Processing 3 part of 3 and uploaded 5242880.0 bytes.
Run Code Online (Sandbox Code Playgroud)

Cal*_*leb 0

这里的问题可能是由于没有完全读取文件引起的。Read可能有点微妙:

Read 将最多 len(p) 个字节读取到 p 中。它返回读取的字节数 (0 <= n <= len(p)) 以及遇到的任何错误。即使 Read 返回 n < len(p),它也可能在调用期间使用所有 p 作为暂存空间。如果某些数据可用,但不是 len(p) 个字节,则 Read 通常会返回可用数据,而不是等待更多数据。

所以你可能应该使用ioReadFullor (更好)io.CopyN

也就是说,我认为您应该尝试切换到官方 AWS Go 软件包。他们有一个方便的上传器,可以为您处理所有这些:

package main

import (
    "log"
    "os"

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

func main() {
    bucketName := "test-bucket"
    keyName := "test-key"
    file, err := os.Open("example")
    if err != nil {
        log.Fatalln(err)
    }
    defer file.Close()

    sess := session.New()
    uploader := s3manager.NewUploader(sess)

    // Perform an upload.
    result, err := uploader.Upload(&s3manager.UploadInput{
        Bucket: &bucketName,
        Key:    &keyName,
        Body:   file,
    })
    if err != nil {
        log.Fatalln(err)
    }
    log.Println(result)
}
Run Code Online (Sandbox Code Playgroud)

您可以在godoc.org上找到更多文档。