Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Http 我可以在没有内容长度头的情况下将文件上传到S3吗?_Http_Rest_Soap_Stream_Amazon S3 - Fatal编程技术网

Http 我可以在没有内容长度头的情况下将文件上传到S3吗?

Http 我可以在没有内容长度头的情况下将文件上传到S3吗?,http,rest,soap,stream,amazon-s3,Http,Rest,Soap,Stream,Amazon S3,我在一台内存有限的机器上工作,我想以流方式将动态生成的(不是从磁盘)文件上传到S3。换句话说,当我开始上传时,我不知道文件大小,但我会在最后知道它。通常,PUT请求有一个内容长度头,但也许有一种方法可以解决这个问题,比如使用多部分或分块内容类型 S3可以支持流式上传。例如,请参见此处: 我的问题是,我可以完成同样的事情而不必在上传开始时指定文件长度吗?请参阅有关HTTP多部分enity请求的更多信息。您可以将文件作为数据块发送到目标 您必须通过将文件以5MiB+块的形式上传。每个块都需要一个内

我在一台内存有限的机器上工作,我想以流方式将动态生成的(不是从磁盘)文件上传到S3。换句话说,当我开始上传时,我不知道文件大小,但我会在最后知道它。通常,PUT请求有一个内容长度头,但也许有一种方法可以解决这个问题,比如使用多部分或分块内容类型

S3可以支持流式上传。例如,请参见此处:


我的问题是,我可以完成同样的事情而不必在上传开始时指定文件长度吗?

请参阅有关HTTP多部分enity请求的更多信息。您可以将文件作为数据块发送到目标

您必须通过将文件以5MiB+块的形式上传。每个块都需要一个内容长度,但您可以避免将大量数据(100MB+)加载到内存中

  • 启动S3多部分上传
  • 将数据收集到缓冲区中,直到该缓冲区达到S3的较低块大小限制(5MiB)。在建立缓冲区时生成MD5校验和
  • 上传该缓冲区作为一部分,存储ETag(读取该缓冲区上的文档)
  • 一旦达到数据的EOF,上传最后一个数据块(可以小于5MiB)
  • 完成多部分上传
S3最多允许10000个部件。因此,通过选择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
这将允许您上传高达1TB的文件(目前单个文件的S3限制为5TB),而不会不必要地浪费内存


关于您的: 他的问题与你的不同——他知道并使用上传前的内容长度。他希望改善这种情况:许多库通过将文件中的所有数据加载到内存来处理上传。在伪代码中,类似以下内容:

data = File.read(file_name)
request = new S3::PutFileRequest()
request.setHeader('Content-Length', data.size)
request.setBody(data)
request.send()
他的解决方案是通过文件系统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()

将此答案放在此处供其他人参考,以防有帮助:

如果您不知道流到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
    }
}

如果您使用的是Node.js,您可以使用类似的插件轻松完成此任务。

您可以使用命令行工具来流式传输linux管道:

$ tar -czf - <my_dir/> | gof3r put --bucket <s3_bucket> --key <s3_object>
$tar-czf-| gof3r put--bucket--key

这些类有Java等价物吗?不知道“Hello world”的长度吗?如果输入是流,它能工作吗?dotnet core不支持,因为Amazon.S3.IO API的同步特性,根据Microsoft。s3distcp中存在一个以OutputStream形式实现的java实现。我已经创建了一个专门用于此的开源库,您在哪里找到了5MiB限制?看起来您现在还可以将cli与pipe-@AlexHall任何python实现一起使用?python库为您提供(流式读写).有没有一种方法可以做什么?