分段上传Amazon S3

时间:2014-08-20 21:29:31

标签: file-upload amazon-web-services amazon-s3 file-transfer

我尝试使用他们的API在Amazon S3上上传文件。我尝试使用他们的示例代码,它创建了文件的各个部分。现在,问题是,如何暂停上传然后恢复?请参阅其文档中给出的以下代码:

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import com.amazonaws.auth.profile.ProfileCredentialsProvider;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.AbortMultipartUploadRequest;
import com.amazonaws.services.s3.model.CompleteMultipartUploadRequest;
import com.amazonaws.services.s3.model.InitiateMultipartUploadRequest;
import com.amazonaws.services.s3.model.InitiateMultipartUploadResult;
import com.amazonaws.services.s3.model.PartETag;
import com.amazonaws.services.s3.model.UploadPartRequest;

public class UploadObjectMPULowLevelAPI {

public static void main(String[] args) throws IOException {
    String existingBucketName  = "*** Provide-Your-Existing-BucketName ***"; 
    String keyName             = "*** Provide-Key-Name ***";
    String filePath            = "*** Provide-File-Path ***";   

    AmazonS3 s3Client = new AmazonS3Client(new ProfileCredentialsProvider());        

    // Create a list of UploadPartResponse objects. You get one of these
    // for each part upload.
    List<PartETag> partETags = new ArrayList<PartETag>();

    // Step 1: Initialize.
    InitiateMultipartUploadRequest initRequest = new 
         InitiateMultipartUploadRequest(existingBucketName, keyName);
    InitiateMultipartUploadResult initResponse = 
                           s3Client.initiateMultipartUpload(initRequest);

    File file = new File(filePath);
    long contentLength = file.length();
    long partSize = 5242880; // Set part size to 5 MB.

    try {
        // Step 2: Upload parts.
        long filePosition = 0;
        for (int i = 1; filePosition < contentLength; i++) {
            // Last part can be less than 5 MB. Adjust part size.
            partSize = Math.min(partSize, (contentLength - filePosition));

            // Create request to upload a part.
            UploadPartRequest uploadRequest = new UploadPartRequest()
                .withBucketName(existingBucketName).withKey(keyName)
                .withUploadId(initResponse.getUploadId()).withPartNumber(i)
                .withFileOffset(filePosition)
                .withFile(file)
                .withPartSize(partSize);

            // Upload part and add response to our list.
            partETags.add(
                    s3Client.uploadPart(uploadRequest).getPartETag());

            filePosition += partSize;
        }

        // Step 3: Complete.
        CompleteMultipartUploadRequest compRequest = new 
                     CompleteMultipartUploadRequest(
                                existingBucketName, 
                                keyName, 
                                initResponse.getUploadId(), 
                                partETags);

        s3Client.completeMultipartUpload(compRequest);
    } 
    catch (Exception e) 
    {
        s3Client.abortMultipartUpload(new AbortMultipartUploadRequest(
                existingBucketName, keyName, initResponse.getUploadId()));
    }
}
}

我还尝试了TransferManager示例,该示例采用Upload对象并调用tryPause(forceCancel)方法。但问题是,每当我尝试暂停它时它就会被取消。

我的问题是,如何使用上述代码暂停和恢复功能?另外,请注意我还要上传具有相同功能的多个文件....非常感谢帮助。

2 个答案:

答案 0 :(得分:0)

我认为你应该使用Transfer Manager样本。如果它被取消,则可能暂停它(使用您正在使用的TransferManager的给定配置)。

这可能是因为你过早地暂停它以使“暂停”意味着除了取消之外的任何东西,你试图使用加密,或者文件不够大。我相信默认的最小文件大小是16MB。但是,您可以更改TransferManager的配置以允许您暂停,具体取决于tryPause失败,除非加密,我认为您无法做任何事情。

如果要为小于该大小的文件启用暂停/恢复,可以在TransferManagerConfiguration中调用setMultipartUploadThreshold(long)方法。如果您希望能够提前暂停,可以使用setMinimumUploadPartSize将其设置为使用较小的块。

在任何情况下,如果可能的话,我会建议你使用TransferManager,因为它是为你做这种事情的。在使用tryPause时,查看为什么传输没有暂停可能会有所帮助。

答案 1 :(得分:0)

TransferManager以异步方式执行上传和下载,不会阻止当前线程。当您调用resumeUpload时,TransferManager会立即返回Upload的引用。您可以使用此参考来查询上载的状态。