Tyl*_*ler 55 rest soap http stream amazon-s3
我正在使用内存有限的机器,我想以流方式将动态生成的(非磁盘)文件上传到S3.换句话说,我在开始上传时不知道文件大小,但最后我会知道它.通常,PUT请求具有Content-Length标头,但是可能有一种解决方法,例如使用multipart或chunked content-type.
S3可以支持流式上传.例如,请看这里:
http://blog.odonnell.nu/posts/streaming-uploads-s3-python-and-poster/
我的问题是,我可以完成同样的事情,而无需在上传开始时指定文件长度吗?
Mar*_*rth 60
您必须通过S3的multipart API以5MiB +块上传文件.每个块都需要Content-Length,但您可以避免将大量数据(100MiB +)加载到内存中.
S3允许最多10,000个零件.因此,通过选择5MiB的零件尺寸,您将能够上传最高50GiB的动态文件.对于大多数用例来说应该足够了.
但是:如果您需要更多,则必须增加零件尺寸.通过使用更高的部件尺寸(例如10MiB)或在上传期间增加它.
First 25 parts: 5MiB (total: 125MiB)
Next 25 parts: 10MiB (total: 375MiB)
Next 25 parts: 25MiB (total: 1GiB)
Next 25 parts: 50MiB (total: 2.25GiB)
After that: 100MiB
Run Code Online (Sandbox Code Playgroud)
这将允许您上传最高1TB的文件(S3的单个文件限制为5TB),而不会浪费不必要的内存.
他的问题与你的问题不同 - 他在上传之前就知道并使用Content-Length.他希望改善这种情况:许多库通过将文件中的所有数据加载到内存来处理上传.在伪代码中,这将是这样的:
data = File.read(file_name)
request = new S3::PutFileRequest()
request.setHeader('Content-Length', data.size)
request.setBody(data)
request.send()
Run Code Online (Sandbox Code Playgroud)
他的解决方案是Content-Length
通过文件系统API 获取它.然后,他将数据从磁盘流式传输到请求流中.在伪代码中:
upload = new S3::PutFileRequestStream()
upload.writeHeader('Content-Length', File.getSize(file_name))
upload.flushHeader()
input = File.open(file_name, File::READONLY_FLAG)
while (data = input.read())
input.write(data)
end
upload.flush()
upload.close()
Run Code Online (Sandbox Code Playgroud)
把这个答案放在这里给其他人以防万一它有帮助:
如果您不知道要流式传输到S3的数据长度,可以使用S3FileInfo
及其OpenWrite()
方法将任意数据写入S3.
var fileInfo = new S3FileInfo(amazonS3Client, "MyBucket", "streamed-file.txt");
using (var outputStream = fileInfo.OpenWrite())
{
using (var streamWriter = new StreamWriter(outputStream))
{
streamWriter.WriteLine("Hello world");
// You can do as many writes as you want here
}
}
Run Code Online (Sandbox Code Playgroud)
您可以使用gof3r命令行工具来流式传输linux管道:
$ tar -czf - <my_dir/> | gof3r put --bucket <s3_bucket> --key <s3_object>
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
48426 次 |
最近记录: |