2015-05-08 151 views
1

如果我們認爲這S3上傳代碼AWS S3的Java SDK:RequestClientOptions.setReadLimit

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

什麼用的setReadLimit方法嗎? AWS SDK Javadoc包含以下說明:

設置用於簽名和重試目的的可選標記和重置讀取限制。 另請參見: InputStream.mark(INT)

是我的假設是正確的,因爲它是提供某種形式的「檢查點」,這樣,如果在網絡中上傳過程中出現故障,API會(內部)從最後的「標記」位置而不是從文件的開頭執行重試?

回答

4

TransferManager確實支持你所描述的「檢查點」,雖然它與readLimit參數沒有直接關係。 S3允許您上傳multiple parts中的大型對象,並且TransferManager會自動爲您做這件事,以便通過certain size進行上傳。如果單個部分的上傳失敗,則基礎AmazonS3Client只需重試該單個部分的上傳。如果您通過傳輸管理器File而不是InputStream,它甚至可以並行上傳文件的多個部分以加快傳輸速度。

當您通過TransferManager(或基礎AmazonS3Client)InputStream而不是File時,將使用readLimit參數。與文件相比,如果您需要重試部分上傳文件,您可以輕鬆查找文件,但InputStream界面的限制性更強。爲了支持對InputStream上傳的重試,AmazonS3Client使用InputStream接口的markreset方法,在每次上傳開始時使用mark流,如果需要重試,則使用。

請注意,mark方法需要一個readlimit參數,並且只有在您事先要求輸入流時纔有義務「記住」多少個字節。某些InputStream通過分配new byte[readlimit]來緩存內存中的底層數據以實現mark,因此如果調用reset時可以重播該數據,這使得使用要上傳的對象的長度(可能是幾GB)盲目mark是危險的。相反,AmazonS3Client默認爲調用mark,其值爲128KB - 如果您的InputStream關心readlimit,這意味着AmazonS3Client將無法在發送超過第一個128KB之後重試失敗的請求。

如果您正在使用這樣的InputStream,並且想要專用更多的內存來緩衝上載的數據,以便AmazonS3Client可以在上傳時進一步重試失敗(或者相反,如果您想使用較小的緩衝區並且可能會看到更多故障),您可以通過setReadLimit調整使用的值。