作者热门文章
- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我想将数据从 http 响应复制到文件和缓冲区。
但是,我不太明白这一点。
最初我有这个:
func DownloadS3(hash string, cluster Cluster, tok *oauth.Token, offset, length int64, f *os.File) ([]byte, error) {
// ... other code not shown ...
resp, err = DoHTTPRequest("GET", s3tok.URL, nil, reqhdr, defaultClientTimeout)
if err != nil {
fmt.Println("Error downloading from cluster:", err)
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != 200 && resp.StatusCode != 206 {
return nil, err
}
// Create buffer to return actual content
buf := make([]byte, resp.ContentLength)
// This actually does copy the whole downloaded data to the file as
// expected. However, I didn't expect io.CopyBuffer to not use the entire
// buffer. It ends up returning a portion of the file.
_, err = io.CopyBuffer(f, resp.Body, buf)
return buf, err
}
所以我真正想要的是类似
_, err = io.CopyBuffer(f, io.TeeReader(resp.Body, buf), nil)
只是,我无法将 buf 传递给 TeeReader,因为它没有实现 writer 接口(interface)。我确定有一个合适的方法,但我摸索着找不到它正在寻找一种有效的方法来做到这一点。
如果不在缓冲区后分配缓冲区,我该如何做到这一点。我试图提高效率。即写入文件并读回它似乎很愚蠢。
我已经尝试过但没有按预期工作。
// Create buffer to return actual content
buf := make([]byte, resp.ContentLength)
_, err = io.CopyBuffer(f, io.TeeReader(resp.Body,bytes.NewBuffer(buf)), nil)
return buf, nil
最佳答案
使用io.MultiWriter和 bytes.Buffer在数据写入文件时获取数据副本:
var buf bytes.Buffer
_, err := io.Copy(io.MultiWriter(f, &buf), resp.Body)
return buf.Bytes(), err
不能保证 io.CopyBuffer 会写入整个缓冲区。当前的实现只会在一次调用 io.Reader.Read 中读取整个响应主体时使用整个缓冲区。在您的示例中,需要不止一次阅读才能吞噬整个响应主体。
关于go - 如何将 http 内容流式传输到文件和缓冲区?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47216029/
我是一名优秀的程序员,十分优秀!