为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
POPMUISE 2021-08-16 15:48:17
我正在构建一个 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 bodydropRef, 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.Bufferhw := &Hasher{&b, sha1.New()}n, err := io.Copy(hw, h.Contents)if err != nil {    return nil, 0, err}return &b, n, nil}
查看完整描述

3 回答

?
烙印99

TA贡献1829条经验 获得超13个赞

io.TeeReader如果您想同时通过 sha1 推送来自 blob 的所有读取,我建议使用。

bodyReader := io.TeeReader(body, hash)

现在,当 bodyReader 在上传过程中被消耗时,哈希值会自动更新。


查看完整回答
反对 回复 2021-08-16
  • 3 回答
  • 0 关注
  • 173 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信