本文介绍如何拷贝文件。

拷贝小文件

拷贝小文件的完整代码请参见 GitHub

此操作的限制条件如下:

  • 用户有源文件的读写权限。
  • 不支持跨地域拷贝。例如,不支持将杭州存储空间里的文件拷贝到青岛。
  • 文件的大小不能超过1GB。

以下代码用于拷贝小文件:

using Aliyun.OSS;
using Aliyun.OSS.Common;
var endpoint = "<yourEndpoint>";
var accessKeyId = "<yourAccessKeyId>";
var accessKeySecret = "<yourAccessKeySecret>";
var sourceBucket = "<yourSourceBucketName>";
var sourceObject = "<yourSourceObjectName>";
var targetBucket = "<yourDestBucketName>";
var targetObject = "<yourDestObjectName>";
// 创建OssClient实例。
var client = new OssClient(endpoint, accessKeyId, accessKeySecret);
try
{
    var metadata = new ObjectMetadata();
    metadata.AddHeader("mk1", "mv1");
    metadata.AddHeader("mk2", "mv2");
    var req = new CopyObjectRequest(sourceBucket, sourceObject, targetBucket, targetObject)
    {
        // 如果NewObjectMetadata为null则为COPY模式(即拷贝源文件的元信息),非null则为REPLACE模式(覆盖源文件的元信息)。
        NewObjectMetadata = metadata 
    };
    // 拷贝文件。
    client.CopyObject(req);
    Console.WriteLine("Copy object succeeded");
}
catch (OssException ex)
{
    Console.WriteLine("Failed with error code: {0}; Error info: {1}. \nRequestID: {2} \tHostID: {3}",
        ex.ErrorCode, ex.Message, ex.RequestId, ex.HostId);
}
catch (Exception ex)
{
    Console.WriteLine("Failed with error info: {0}", ex.Message);
}

拷贝大文件

拷贝大文件完整代码请参见GitHub

  • 分片拷贝

    对于大于1GB的文件,建议使用分片拷贝,步骤如下:

    1. 使用 InitiateMultipartUploadRequest 方法来初始化一个分片上传事件。
    2. 使用 UploadPartCopy 方法进行分片拷贝。
    3. 使用 CompleteMultipartUpload 方法完成文件拷贝。

    以下代码用于分片拷贝文件:

    using Aliyun.OSS;
    var endpoint = "<yourEndpoint>";
    var accessKeyId = "<yourAccessKeyId>";
    var accessKeySecret = "<yourAccessKeySecret>";
    var sourceBucket = "<yourSourceBucketName>";
    var sourceObject = "<yourSourceObjectName>";
    var targetBucket = "<yourDestBucketName>";
    var targetObject = "<yourDestObjectName>";
    var uploadId = "";
    var partSize = 50 * 1024 * 1024;
    // 创建OssClient实例。
    var client = new OssClient(endpoint, accessKeyId, accessKeySecret);
    try
    {
        // 初始化拷贝任务。可以通过InitiateMultipartUploadRequest指定目标文件元信息。
        var request = new InitiateMultipartUploadRequest(targetBucket, targetObject);
        var result = client.InitiateMultipartUpload(request);
        // 打印uploadId。
        uploadId = result.UploadId;
        Console.WriteLine("Init multipart upload succeeded, Upload Id: {0}", result.UploadId);
        // 计算分片数。
        var metadata = client.GetObjectMetadata(sourceBucket, sourceObject);
        var fileSize = metadata.ContentLength;
        var partCount = (int)fileSize / partSize;
        if (fileSize % partSize != 0)
        {
            partCount++;
        }
        // 开始分片拷贝。
        var partETags = new List<PartETag>();
        for (var i = 0; i < partCount; i++)
        {
            var skipBytes = (long)partSize * i;
            var size = (partSize < fileSize - skipBytes) ? partSize : (fileSize - skipBytes);
            // 创建UploadPartCopyRequest。可以通过UploadPartCopyRequest指定限定条件。
            var uploadPartCopyRequest = new UploadPartCopyRequest(targetBucket, targetObject, sourceBucket, sourceObject, uploadId)
                {
                    PartSize = size,
                    PartNumber = i + 1,
                    // BeginIndex用来定位此次上传分片开始所对应的位置。
                    BeginIndex = skipBytes
                };
            // 调用uploadPartCopy方法来拷贝每一个分片。
            var uploadPartCopyResult = client.UploadPartCopy(uploadPartCopyRequest);
            Console.WriteLine("UploadPartCopy : {0}", i);
            partETags.Add(uploadPartCopyResult.PartETag);
        }
        // 完成分片拷贝。
        var completeMultipartUploadRequest =
        new CompleteMultipartUploadRequest(targetBucket, targetObject, uploadId);
        // partETags为分片上传中保存的partETag的列表,OSS收到用户提交的此列表后,会逐一验证每个数据分片的有效性。全部验证通过后,OSS会将这些分片合成一个完整的文件。
        foreach (var partETag in partETags)
        {
            completeMultipartUploadRequest.PartETags.Add(partETag);
        }
        var completeMultipartUploadResult = client.CompleteMultipartUpload(completeMultipartUploadRequest);
        Console.WriteLine("CompleteMultipartUpload succeeded");
    }
    catch (OssException ex)
    {
        Console.WriteLine("Failed with error code: {0}; Error info: {1}. \nRequestID: {2} \tHostID: {3}",
            ex.ErrorCode, ex.Message, ex.RequestId, ex.HostId);
    }
    catch (Exception ex)
    {
        Console.WriteLine("Failed with error info: {0}", ex.Message);
    }
  • 断点续传拷贝

    如果拷贝中断,可通过断点续传继续拷贝。 断点续传拷贝的完整代码请参见GitHub

    以下代码用于断点续传拷贝:

    using Aliyun.OSS;
    var endpoint = "<yourEndpoint>";
    var accessKeyId = "<yourAccessKeyId>";
    var accessKeySecret = "<yourAccessKeySecret>";
    var sourceBucket = "<yourSourceBucketName>";
    var sourceObject = "<yourSourceObjectName>";
    var targetBucket = "<yourDestBucketName>";
    var targetObject = "<yourDestObjectName>";
    var checkpointDir = @"<yourCheckpointDir>";
    // 创建OssClient实例。
    var client = new OssClient(endpoint, accessKeyId, accessKeySecret);
    try
    {
        var request = new CopyObjectRequest(sourceBucket, sourceObject, targetBucket, targetObject);
        // checkpointDir目录中会保存断点续传的中间状态,用于失败后,下次继续拷贝。如果checkpointDir为null,断点续传功能不会生效,每次都会重新拷贝。
        client.ResumableCopyObject(request, checkpointDir);
        Console.WriteLine("Resumable copy new object:{0} succeeded", request.DestinationKey);
    }
    catch (Exception ex)
    {
        Console.WriteLine("Resumable copy new object failed, {0}", ex.Message);
    }