gpt4 book ai didi

go - 如何从 io.ReadCloser 转到 io.ReadSeeker?

转载 作者:IT老高 更新时间:2023-10-28 13:05:10 27 4
gpt4 key购买 nike

我正在尝试从 S3 下载文件并将该文件上传到 S3 中的另一个存储桶。 Copy API 在这里不起作用,因为我被告知不要使用它。

从 S3 获取对象有一个 response.Body,它是一个 io.ReadCloser 并且要上传该文件,有效负载需要一个 Body那是一个 io.ReadSeeker

我能解决这个问题的唯一方法是将 response.Body 保存到一个文件中,然后将该文件作为 io.ReadSeeker 传递。这需要先将整个文件写入磁盘,然后再从磁盘读取整个文件,这听起来很错误。

我想做的是:

resp, _ := conn.GetObject(&s3.GetObjectInput{Key: "bla"})
conn.PutObject(&s3.PutObjectInput{Body: resp.Body}) // resp.Body is an io.ReadCloser and the field type expects an io.ReadSeeker

问题是,我如何以最有效的方式从 io.ReadCloser 转到 io.ReadSeeker

最佳答案

io.ReadSeeker是对基本 Read()Seek() 方法进行分组的接口(interface)。 Seek()方法的定义:

Seek(offset int64, whence int) (int64, error)

Seek() 方法的实现需要能够在源中查找任何地方,这要求所有源是可用或可重现。文件就是一个很好的例子,该文件被永久保存到您的磁盘中,并且可以随时读取其中的任何部分。

response.Body 被实现为从底层 TCP 连接中读取。从底层 TCP 连接中读取数据会为您提供另一端的客户端发送给您的数据。数据不会被缓存,客户端不会根据请求再次向您发送数据。这就是为什么 response.Body 没有实现 io.Seeker (因此 io.ReadSeeker 也是如此)。

因此,为了从 io.Readerio.ReadCloser 获取 io.ReadSeeker,您需要缓存 所有数据,以便它可以根据请求搜索其中的任何位置。

这种缓存机制可能会像您提到的那样将其写入文件,或者您可以使用 ioutil.ReadAll() 将所有内容读入内存,读入 []byte , 然后你可以使用 bytes.NewReader()[]byte 获取 io.ReadSeeker。当然,这有其局限性:所有内容都必须适合内存,而且您可能不希望为该文件复制操作保留该内存量。

总而言之,io.Seekerio.ReadSeeker 的实现需要所有源数据都可用,因此最好的办法是将其写入文件,或者对于将所有小文件读入 []byte 并流式传输该 byte slice 的内容。

关于go - 如何从 io.ReadCloser 转到 io.ReadSeeker?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37718191/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com