Http 上传一个文件';s字节范围与流和进度

Http 上传一个文件';s字节范围与流和进度,http,go,upload,progress,Http,Go,Upload,Progress,我刚开始学围棋,需要一些帮助。我想从文件上传一定范围的字节 我已经通过将字节读入缓冲区完成了这项工作。但这会增加内存使用。 我不想将字节读入内存,而是希望在上传时对它们进行流式处理,并有一个上传进度。我在Node.js中做了类似的事情,但很难将拼图拼凑起来。 我现在拥有的代码如下所示: func uploadChunk(id, mimeType, uploadURL, filePath string, offset, size uint) { // open file file,

我刚开始学围棋,需要一些帮助。我想从文件上传一定范围的字节

我已经通过将字节读入缓冲区完成了这项工作。但这会增加内存使用。 我不想将字节读入内存,而是希望在上传时对它们进行流式处理,并有一个上传进度。我在Node.js中做了类似的事情,但很难将拼图拼凑起来。 我现在拥有的代码如下所示:

func uploadChunk(id, mimeType, uploadURL, filePath string, offset, size uint) {
    // open file
    file, err := os.Open(filePath)
    panicCheck(err, ErrorFileRead) // custom error handler
    defer file.Close()

    // move to the proper byte
    file.Seek(int64(offset), 0)

    // read byte chunk into buffer
    buffer := make([]byte, size)
    file.Read(buffer)
    fileReader := bytes.NewReader(buffer)

    request, err := http.NewRequest(http.MethodPut, uploadURL, fileReader)

    client := &http.Client{
        Timeout: time.Second * 10,
    }

    response, err := client.Do(request)
    panicCheck(err, ErrorFileRead)

    defer response.Body.Close()

    b, err := httputil.DumpResponse(response, true)
    panicCheck(err, ErrorFileRead)
    fmt.Println("response\n", string(b))
}
你们能帮我弄清楚如何流式传输并获得上传进度吗

谢谢

您可以使用包装文件,只读取所需的数据量。返回的实现是一个
*io.LimitedReader

file.Seek(int64(offset), 0)
fileReader := io.LimitReader(file, size)

request, err := http.NewRequest(http.MethodPut, uploadURL, fileReader)
对于S3,您需要通过显式设置ContentLength来确保不使用分块编码:

request.ContentLength = size

至于上传进度,请参见:

我不理解这个示例,因为您有一个
文件
,但您没有对其执行任何操作。您不只是将该文件用作
NewRequest
的主体吗?谢谢@JimB,我刚刚编辑了示例代码。我没有添加
file.Read(buffer)
是的,但是为什么不直接将
file
传递到
http.NewRequest
?@JimB我只想从文件上传一系列字节。不是整个档案。这就是为什么我要执行
file.Seek(偏移量,0)
。函数的参数采用偏移量和大小。大小决定应该读取多少字节。看起来像我需要的,但与PUT上载一起,它会给我一个
501未实现
服务器错误<代码>您提供的标题暗示未实现的功能传输编码。你知道这是什么原因吗?@ThomasSzabo:这是不是来自S3?没错。我正试图用一个预先签名的文件上传到S3URL@ThomasSzabo:S3很奇怪(不兼容),因为它不接受分块编码。尝试设置
request.ContentLength=size
。哇!这修复了501错误。我以前用
request.Header.Set(“Content-Length”,fmt.Sprintf(“%d”,size))
尝试过,但没有成功。