分段上传到Amazon S3会覆盖最后一部分

时间:2014-04-14 05:46:06

标签: c# amazon-s3

我正在关注使用.NET客户端库进行分段上传的here文档。

我遇到的问题是发送到S3的每个部分都会覆盖最后一部分。所以换句话说,我的每件10kb(一次尝试5mb),每次上传都会覆盖前一个。我做错了什么?

这就是我所拥有的

var fileTransferUtility = new TransferUtility(_s3Client);
var request = new TransferUtilityUploadRequest
    {
        BucketName = "mybucket",
        InputStream = stream,
        StorageClass = S3StorageClass.ReducedRedundancy,
        PartSize = stream.Length,//stream is 10,000 bytes at a time
        Key = fileName
    };

修改

这是执行分段上传的工作代码

public UploadPartResponse UploadChunk(Stream stream, string fileName, string uploadId, List<PartETag> eTags, int partNumber, bool lastPart)
{
    stream.Position = 0;

    //Step 1: build and send a multi upload request
    if (partNumber == 1)
    {
        var initiateRequest = new InitiateMultipartUploadRequest
        {
            BucketName = _settings.Bucket,
            Key = fileName
        };

        var initResponse = _s3Client.InitiateMultipartUpload(initiateRequest);
        uploadId = initResponse.UploadId;
    }

    //Step 2: upload each chunk (this is run for every chunk unlike the other steps which are run once)
    var uploadRequest = new UploadPartRequest
                        {
                            BucketName = _settings.Bucket,
                            Key = fileName,
                            UploadId = uploadId,
                            PartNumber = partNumber,
                            InputStream = stream,
                            IsLastPart = lastPart,
                            PartSize = stream.Length
                        };

    var response = _s3Client.UploadPart(uploadRequest);

    //Step 3: build and send the multipart complete request
    if (lastPart)
    {
        eTags.Add(new PartETag
        {
            PartNumber = partNumber,
            ETag = response.ETag
        });

        var completeRequest = new CompleteMultipartUploadRequest
        {
            BucketName = _settings.Bucket,
            Key = fileName,
            UploadId = uploadId,
            PartETags = eTags
        };

        try
        {
            _s3Client.CompleteMultipartUpload(completeRequest);
        }
        catch
        {
            //do some logging and return null response
            return null;
        }
    }

    response.ResponseMetadata.Metadata["uploadid"] = uploadRequest.UploadId;
    return response;
}

如果你有一个被分成10个块的流,你将会使用这个方法10次,在第一个块上你会遇到第1步&amp; 2,块2-9只有第2步,最后只有第3步。你需要将每个响应的上传ID和etag发回给你的客户端。在步骤3,您将需要为所有部分提供etag,否则它将在S3上将文件放在一起而不再增加1个部分。在我的客户端,我有一个隐藏的字段,我坚持etag列表(逗号分隔)。

1 个答案:

答案 0 :(得分:4)

此代码设置的是一个请求,它将仅上传一个包含一个部分的对象,因为您传入一个流并将部件大小设置为整个流的长度。

使用TransferUtility的目的是为它提供一个大的流或文件路径,并将部分大小设置为您希望流分解为的增量。您也可以将PartSize留空,这将使用默认的零件尺寸。