AWS S3 Java SDK:RequestClientOptions.setReadLimit

lol*_*ski 1 java scala amazon-s3 amazon-web-services aws-sdk

如果我们考虑这个S3上传代码

val tm: TransferManager = ???
val putRequest = new PutObjectRequest(bucketName, keyName, inputStream, metaData)
putRequest.setStorageClass(storageClass)
putRequest.getRequestClientOptions.setReadLimit(100000)
tm.upload(putRequest)
Run Code Online (Sandbox Code Playgroud)

setReadLimit方法有什么用?在AWS SDK的Javadoc包含以下说明:

设置用于签名和重试目的的可选标记和重置读取限制.另请参见:InputStream.mark(int)

我的假设是正确的,因为它是提供某种"检查点",这样如果网络在上传过程中失败,API将(内部)从最后一个"标记"位置执行重试,而不是从文件的开头?

Dav*_*ray 6

TransferManager确实支持您所描述的"检查点",尽管它与readLimit参数没有直接关系.S3允许您在多个部分上传大型对象,TransferManager会自动为您执行此操作,以便上传超过一定大小的内容.如果单个部件的上载失败,则底层AmazonS3Client仅需要重试该单个部件的上载.如果您传递TransferManager File而不是a InputStream,它甚至可以并行上传文件的多个部分以加快传输速度.

传递TransferManager(或底层的AmazonS3Client)InputStream而不是a 时,使用readLimit参数File.与文件相比,如果您需要重试部分上传,可以轻松搜索文件,则InputStream界面的限制性要大得多.为了支持InputStream上传的重试,AmazonS3Client使用InputStream接口的markreset方法,在mark每次上传开始时使用流,reset如果需要重试,则使用标记.

请注意,mark方法接受一个readlimit参数,并且只需要提前"记住"来自InputStream的字节数.一些InputStream mark通过分配一个new byte[readlimit]来缓冲内存中的底层数据来实现,因此如果调用reset就可以重放它,这使得盲目地mark使用要上载的对象的长度(可能是几千兆字节)是危险的.相反,AmazonS3Client默认mark使用128KB的值进行调用- 如果您的InputStream关心readlimit,这意味着AmazonS3Client在发送超过前128KB的请求后将无法重试失败的请求.

如果你正在使用这样的InputStream并且想要更多的内存来缓冲上传的数据,那么AmazonS3Client可以在上传中进一步重试失败(或者相反,如果你想使用更小的缓冲区并且可能会看到更多的失败),您可以调整通过使用的值setReadLimit.