全部產品
Search
文件中心

Object Storage Service:.NET上傳檔案

更新時間:Nov 26, 2024

本文介紹如何在受版本控制的儲存空間(Bucket)中上傳檔案(Object)。

注意事項

  • 本文以華東1(杭州)外網Endpoint為例。如果您希望通過與OSS同地區的其他阿里雲產品訪問OSS,請使用內網Endpoint。關於OSS支援的Region與Endpoint的對應關係,請參見OSS地區和訪問網域名稱

  • 本文以OSS網域名稱建立OSSClient為例。如果您希望通過自訂網域名、STS等方式建立OSSClient,請參見初始化

  • 要上傳檔案,您必須有oss:PutObject許可權。具體操作,請參見為RAM使用者授權自訂的權限原則

簡單上傳

在已開啟版本控制的Bucket中,OSS會為新添加的Object自動產生唯一的版本ID,並在響應header中通過x-oss-version-id形式返回。在暫停了版本控制的Bucket中,新添加的Object的版本ID為“null”,上傳同名Object,後一次會覆蓋前一次上傳的檔案內容。OSS保證同一個Object只會有一個版本ID為“null”。

以下代碼用於簡單上傳:

using System.Text;
using Aliyun.OSS;
// yourEndpoint填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。
var endpoint = "yourEndpoint";
// 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
var accessKeyId = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_ID");
var accessKeySecret = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_SECRET");
// 填寫Bucket名稱,例如examplebucket。
var bucketName = "examplebucket";
// 填寫Object完整路徑,完整路徑中不能包含Bucket名稱,例如exampledir/exampleobject.txt。
var objectName = "exampleobject.txt";
var objectContent = "More than just cloud.";
// 填寫Bucket所在地區對應的Region。以華東1(杭州)為例,Region填寫為cn-hangzhou。
const string region = "cn-hangzhou";

// 建立ClientConfiguration執行個體,按照您的需要修改預設參數。
var conf = new ClientConfiguration();

// 設定v4簽名。
conf.SignatureVersion = SignatureVersion.V4;

// 建立OssClient執行個體。
var client = new OssClient(endpoint, accessKeyId, accessKeySecret, conf);
c.SetRegion(region);
try
{
    byte[] binaryData = Encoding.ASCII.GetBytes(objectContent);
    MemoryStream requestContent = new MemoryStream(binaryData);
    // 上傳檔案。
    var result = client.PutObject(bucketName, objectName, requestContent);
    Console.WriteLine("Put object succeeded versionid : {0}", result.VersionId);
}
catch (Exception ex)
{
    Console.WriteLine("Put object failed, {0}", ex.Message);
}

追加上傳

在受版本控制的Bucket中,僅支援對於目前的版本為Appendable類型的Object執行追加(AppendObject)操作,不支援對於歷史版本為Appendable類型的Object執行AppendObject操作。

說明
  • 對目前的版本為Appendable類型的Object執行AppendObject操作時,OSS不會為該Appendable類型的Object產生歷史版本。

  • 對目前的版本為Appendable類型的Object執行PutObject或DeleteObject操作時,OSS會將該Appendable類型的Object保留為歷史版本,且該Object不允許繼續追加。

  • 不支援對目前的版本為非Appendable類型的Object(包括Normal Object、Delete Marker等)執行AppendObject操作。

以下代碼用於追加上傳:

using Aliyun.OSS;
// yourEndpoint填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。
var endpoint = "yourEndpoint";
// 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
var accessKeyId = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_ID");
var accessKeySecret = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_SECRET");
// 填寫Bucket名稱,例如examplebucket。
var bucketName = "examplebucket";
// 填寫Object完整路徑,完整路徑中不能包含Bucket名稱,例如exampledir/exampleobject.txt。
var objectName = "exampleobject.txt";
// 填寫本地檔案完整路徑,例如D:\\localpath\\examplefile.txt。如果未指定本地路徑,則預設從樣本程式所屬專案對應本地路徑中上傳檔案。
var localFilename = "D:\\localpath\\examplefile.txt";
// 填寫Bucket所在地區對應的Region。以華東1(杭州)為例,Region填寫為cn-hangzhou。
const string region = "cn-hangzhou";

// 建立ClientConfiguration執行個體,按照您的需要修改預設參數。
var conf = new ClientConfiguration();

// 設定v4簽名。
conf.SignatureVersion = SignatureVersion.V4;

// 建立OssClient執行個體。
var client = new OssClient(endpoint, accessKeyId, accessKeySecret, conf);
c.SetRegion(region);
// 第一次追加的位置是0,傳回值為下一次追加的位置。後續追加的位置是追加前檔案的長度。
long position = 0;
try
{
    var metadata = client.GetObjectMetadata(bucketName, objectName);
    position = metadata.ContentLength;
}
catch (Exception) { }
try
{
    using (var fs = File.Open(localFilename, FileMode.Open))
    {
        var request = new AppendObjectRequest(bucketName, objectName)
        {
            ObjectMetadata = new ObjectMetadata(),
            Content = fs,
            Position = position
        };
        // 追加檔案。
        var result = client.AppendObject(request);
        // 設定檔案的追加位置。
        position = result.NextAppendPosition;
        Console.WriteLine("Append object succeeded, next append position:{0}, vesionid:{1}", position, result.VersionId);
    }
    // 擷取追加位置,再次追加檔案。
    using (var fs = File.Open(localFilename, FileMode.Open))
    {
        var request = new AppendObjectRequest(bucketName, objectName)
        {
            ObjectMetadata = new ObjectMetadata(),
            Content = fs,
            Position = position
        };
        var result = client.AppendObject(request);
        position = result.NextAppendPosition;
        Console.WriteLine("Append object succeeded, next append position:{0}, vesionid:{1}", position, result.VersionId);
    }
}
catch (Exception ex)
{
    Console.WriteLine("Append object failed, {0}", ex.Message);
}

分區上傳

在受版本控制的Bucket中,調用CompleteMultipartUpload介面來完成整個檔案的分區上傳,OSS會為整個檔案產生唯一的版本ID,並在響應header中以x-oss-version-id的形式返回。

以下代碼用於分區上傳:

using Aliyun.OSS;
// yourEndpoint填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。
var endpoint = "yourEndpoint";
// 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
var accessKeyId = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_ID");
var accessKeySecret = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_SECRET");
// 填寫Bucket名稱,例如examplebucket。
var bucketName = "examplebucket";
// 填寫Object完整路徑,完整路徑中不能包含Bucket名稱,例如exampledir/exampleobject.txt。
var objectName = "exampledir/exampleobject.txt";
// 填寫本地檔案完整路徑,例如D:\\localpath\\examplefile.txt。如果未指定本地路徑,則預設從樣本程式所屬專案對應本地路徑中上傳檔案。
var localFilename = "D:\\localpath\\examplefile.txt";
// 填寫Bucket所在地區對應的Region。以華東1(杭州)為例,Region填寫為cn-hangzhou。
const string region = "cn-hangzhou";

// 建立ClientConfiguration執行個體,按照您的需要修改預設參數。
var conf = new ClientConfiguration();

// 設定v4簽名。
conf.SignatureVersion = SignatureVersion.V4;

// 建立OssClient執行個體。
var client = new OssClient(endpoint, accessKeyId, accessKeySecret, conf);
c.SetRegion(region);
// 初始化分區上傳。
var uploadId = "";
try
{
    // 定義上傳檔案的名字和所屬儲存空間。在InitiateMultipartUploadRequest中,可以設定ObjectMeta,但不必指定其中的ContentLength。
    var request = new InitiateMultipartUploadRequest(bucketName, objectName);
    var result = client.InitiateMultipartUpload(request);
    uploadId = result.UploadId;
    // 列印UploadId。
    Console.WriteLine("Init multi part upload succeeded");
    Console.WriteLine("Upload Id:{0}", result.UploadId);
}
catch (Exception ex)
{
    Console.WriteLine("Init multi part upload failed, {0}", ex.Message);
}
// 計算分區總數。
var partSize = 100 * 1024;
var fi = new FileInfo(localFilename);
var fileSize = fi.Length;
var partCount = fileSize / partSize;
if (fileSize % partSize != 0)
{
    partCount++;
}
// 開始分區上傳。partETags是儲存partETag的列表,OSS收到使用者提交的分區列表後,會逐一驗證每個分區資料的有效性。 當所有的資料分區通過驗證後,OSS會將這些分區組合成一個完整的檔案。
var partETags = new List<PartETag>();
try
{
    using (var fs = File.Open(localFilename, FileMode.Open))
    {
        for (var i = 0; i < partCount; i++)
        {
            var skipBytes = (long)partSize * i;
            // 定位到本次上傳起始位置。
            fs.Seek(skipBytes, 0);
            // 計算本次上傳的片大小,最後一片為剩餘的資料大小。
            var size = (partSize < fileSize - skipBytes) ? partSize : (fileSize - skipBytes);
            var request = new UploadPartRequest(bucketName, objectName, uploadId)
            {
                InputStream = fs,
                PartSize = size,
                PartNumber = i + 1
            };
            // 調用UploadPart介面執行上傳功能,返回結果中包含了這個資料片的ETag值。
            var result = client.UploadPart(request);
            partETags.Add(result.PartETag);
            Console.WriteLine("finish {0}/{1}", partETags.Count, partCount);
        }
        Console.WriteLine("Put multi part upload succeeded");
    }
}
catch (Exception ex)
{
    Console.WriteLine("Put multi part upload failed, {0}", ex.Message);
}
// 完成分區上傳。
try
{
    var completeMultipartUploadRequest = new CompleteMultipartUploadRequest(bucketName, objectName, uploadId);
    foreach (var partETag in partETags)
    {
        completeMultipartUploadRequest.PartETags.Add(partETag);
    }
    var result = client.CompleteMultipartUpload(completeMultipartUploadRequest);
    Console.WriteLine("CompleteMultipartUpload succeeded, vesionid:{0}", result.VersionId);
}
catch (Exception ex)
{
    Console.WriteLine("complete multi part failed, {0}", ex.Message);
}

相關文檔