Golang io.copy 在请求正文上两次

我正在构建一个 blob 存储系统,我选择 Go 作为编程语言。我创建了一个流来将多部分文件从客户端上传到 Blob 服务器。


流工作正常,但我想从请求正文中创建一个 sha1 哈希。我需要 io.Copy 身体两次。sha1 被创建,但之后多部分流 0 字节。


用于创建哈希

用于将主体流式传输为多部分

知道我该怎么做吗?


客户端上传


func (c *Client) Upload(h *UploadHandle) (*PutResult, error) {

body, bodySize, err := h.Read()

if err != nil {

    return nil, err

}


// Creating a sha1 hash from the bytes of body

dropRef, err := drop.Sha1FromReader(body)

if err != nil {

    return nil, err

}


bodyReader, bodyWriter := io.Pipe()

writer := multipart.NewWriter(bodyWriter)


errChan := make(chan error, 1)

go func() {

    defer bodyWriter.Close()

    part, err := writer.CreateFormFile(dropRef, dropRef)

    if err != nil {

        errChan <- err

        return

    }

    if _, err := io.Copy(part, body); err != nil {

        errChan <- err

        return

    }

    if err = writer.Close(); err != nil {

        errChan <- err

    }

}()


req, err := http.NewRequest("POST", c.Server+"/drops/upload", bodyReader)

req.Header.Add("Content-Type", writer.FormDataContentType())

resp, err := c.Do(req)

if err != nil {

    return nil, err

}

  .....

 }

sha1 函数


func Sha1FromReader(src io.Reader) (string, error) {

hash := sha1.New()

_, err := io.Copy(hash, src)

if err != nil {

    return "", err

}

return hex.EncodeToString(hash.Sum(nil)), nil

}


上传句柄


func (h *UploadHandle) Read() (io.Reader, int64, error) {

var b bytes.Buffer


hw := &Hasher{&b, sha1.New()}

n, err := io.Copy(hw, h.Contents)


if err != nil {

    return nil, 0, err

}


return &b, n, nil

}


POPMUISE
浏览 174回答 3
3回答

烙印99

io.TeeReader如果您想同时通过 sha1 推送来自 blob 的所有读取,我建议使用。bodyReader&nbsp;:=&nbsp;io.TeeReader(body,&nbsp;hash)现在,当 bodyReader 在上传过程中被消耗时,哈希值会自动更新。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go