OSS支持使用对象标签(Object Tagging)对存储的Object进行分类,您可以针对同标签的Object设置生命周期规则、访问权限等。
背景信息
设置对象标签时,请注意以下事项:
- 您可以在上传Object时设置对象标签,也可以对已上传Object设置对象标签。设置对象标签时,若对象已有标签,则覆盖原标签。设置对象标签的详情请参见PutObjectTagging。
- 设置对象标签时要求请求者有PutObjectTagging权限。
- 更改标签时不会更新Object的Last‑Modified时间。
- 标签合法字符集包括大小写字母、数字、空格和以下符号:
+‑=._:/
对象标签使用一组键值对(Key-Value)来标记对象。对象标签的详情请参见对象标签。
上传Object时添加对象标签
以下分别介绍简单上传、分片上传、追加上传以及断点续传上传场景下为上传的Object添加对象标签的示例。
- 简单上传时添加对象标签
以下代码用于简单上传时添加对象标签:
using System.Text; using Aliyun.OSS; using System.Text; using Aliyun.OSS.Util; var endpoint = "<yourEndpoint>"; var accessKeyId = "<yourAccessKeyId>"; var accessKeySecret = "<yourAccessKeySecret>"; var bucketName = "<yourBucketName>"; var objectName = "<yourObjectName>"; var objectContent = "More than just cloud."; String UrlEncodeKey(String key) { const string CharsetName = "utf-8"; const char separator = '/'; var segments = key.Split(separator); var encodedKey = new StringBuilder(); encodedKey.Append(HttpUtils.EncodeUri(segments[0], CharsetName)); for (var i = 1; i < segments.Length; i++) encodedKey.Append(separator).Append(HttpUtils.EncodeUri(segments[i], CharsetName)); if (key.EndsWith(separator.ToString())) { // String#split ignores trailing empty strings, e.g., "a/b/" will be split as a 2-entries array, // so we have to append all the trailing slash to the uri. foreach (var ch in key) { if (ch == separator) encodedKey.Append(separator); else break; } } return encodedKey.ToString(); } // 创建OssClient实例。 var client = new OssClient(endpoint, accessKeyId, accessKeySecret); try { byte[] binaryData = Encoding.ASCII.GetBytes(objectContent); MemoryStream requestContent = new MemoryStream(binaryData); var meta = new ObjectMetadata(); // 在HTTP header中设置标签信息。 string str = UrlEncodeKey("key1") + "=" + UrlEncodeKey("key1") + "&" + UrlEncodeKey("key2") + "=" + UrlEncodeKey("key2"); meta.AddHeader("x-oss-tagging", str); var putRequest = new PutObjectRequest(bucketName, objectName, requestContent); putRequest.Metadata = meta; // 上传文件的同时对文件设置标签。 client.PutObject(putRequest); Console.WriteLine("Put object succeeded"); } catch (Exception ex) { Console.WriteLine("Put object failed, {0}", ex.Message); }
- 分片上传时添加对象标签
以下代码用于分片上传时添加对象标签:
using Aliyun.OSS; using System.Text; var endpoint = "<yourEndpoint>"; var accessKeyId = "<yourAccessKeyId>"; var accessKeySecret = "<yourAccessKeySecret>"; var bucketName = "<yourBucketName>"; var objectName = "<yourObjectName>"; var localFilename = "<yourLocalFilename>"; String UrlEncodeKey(String key) { const string CharsetName = "utf-8"; const char separator = '/'; var segments = key.Split(separator); var encodedKey = new StringBuilder(); encodedKey.Append(HttpUtils.EncodeUri(segments[0], CharsetName)); for (var i = 1; i < segments.Length; i++) encodedKey.Append(separator).Append(HttpUtils.EncodeUri(segments[i], CharsetName)); if (key.EndsWith(separator.ToString())) { // String#split ignores trailing empty strings, e.g., "a/b/" will be split as a 2-entries array, // so we have to append all the trailing slash to the uri. foreach (var ch in key) { if (ch == separator) encodedKey.Append(separator); else break; } } return encodedKey.ToString(); } // 创建OssClient实例。 var client = new OssClient(endpoint, accessKeyId, accessKeySecret); // 初始化分片上传。 var uploadId = ""; try { // 设置上传Object及所属存储空间的名称。您可以在InitiateMultipartUploadRequest中设置ObjectMeta,但不必指定ContentLength。 var request = new InitiateMultipartUploadRequest(bucketName, objectName); var meta = new ObjectMetadata(); // 在HTTP header中设置标签信息。 string str = UrlEncodeKey("key1") + "=" + UrlEncodeKey("key1") + "&" + UrlEncodeKey("key2") + "=" + UrlEncodeKey("key2"); meta.AddHeader("x-oss-tagging", str); request.Metadata = meta; 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("complete multi part succeeded"); } catch (Exception ex) { Console.WriteLine("complete multi part failed, {0}", ex.Message); }
- 追加上传时添加对象标签
以下代码用于追加上传时添加对象标签:
using Aliyun.OSS; using System.Text; var endpoint = "<yourEndpoint>"; var accessKeyId = "<yourAccessKeyId>"; var accessKeySecret = "<yourAccessKeySecret>"; var bucketName = "<yourBucketName>"; var objectName = "<yourObjectName>"; var localFilename = "<yourLocalFilename>"; String UrlEncodeKey(String key) { const string CharsetName = "utf-8"; const char separator = '/'; var segments = key.Split(separator); var encodedKey = new StringBuilder(); encodedKey.Append(HttpUtils.EncodeUri(segments[0], CharsetName)); for (var i = 1; i < segments.Length; i++) encodedKey.Append(separator).Append(HttpUtils.EncodeUri(segments[i], CharsetName)); if (key.EndsWith(separator.ToString())) { // String#split ignores trailing empty strings, e.g., "a/b/" will be split as a 2-entries array, // so we have to append all the trailing slash to the uri. foreach (var ch in key) { if (ch == separator) encodedKey.Append(separator); else break; } } return encodedKey.ToString(); } // 创建OssClient实例。 var client = new OssClient(endpoint, accessKeyId, accessKeySecret); // 第一次追加的位置是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 meta = new ObjectMetadata(); // 在HTTP header中设置标签信息。 string str = UrlEncodeKey("key1") + "=" + UrlEncodeKey("key1") + "&" + UrlEncodeKey("key2") + "=" + UrlEncodeKey("key2"); meta.AddHeader("x-oss-tagging", str); request.Metadata = meta; // 第一次追加。只有第一次追加上传时设置的标签生效。 var result = client.AppendObject(request); // 设置文件的追加位置。 position = result.NextAppendPosition; Console.WriteLine("Append object succeeded, next append position:{0}", position); } // 获取追加位置,再次追加文件。 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}", position); } } catch (Exception ex) { Console.WriteLine("Append object failed, {0}", ex.Message); }
- 断点续传上传时添加对象标签
以下代码用于断点续传上传时添加对象标签:
using Aliyun.OSS; using Aliyun.OSS.Common; using System.Text; var endpoint = "<yourEndpoint>"; var accessKeyId = "<yourAccessKeyId>"; var accessKeySecret = "<yourAccessKeySecret>"; var bucketName = "<yourBucketName>"; var objectName = "<yourObjectName>"; var localFilename = "<yourLocalFilename>"; string checkpointDir = "<yourCheckpointDir>"; String UrlEncodeKey(String key) { const string CharsetName = "utf-8"; const char separator = '/'; var segments = key.Split(separator); var encodedKey = new StringBuilder(); encodedKey.Append(HttpUtils.EncodeUri(segments[0], CharsetName)); for (var i = 1; i < segments.Length; i++) encodedKey.Append(separator).Append(HttpUtils.EncodeUri(segments[i], CharsetName)); if (key.EndsWith(separator.ToString())) { // String#split ignores trailing empty strings, e.g., "a/b/" will be split as a 2-entries array, // so we have to append all the trailing slash to the uri. foreach (var ch in key) { if (ch == separator) encodedKey.Append(separator); else break; } } return encodedKey.ToString(); } // 创建OssClient实例。 var client = new OssClient(endpoint, accessKeyId, accessKeySecret); try { // 通过UploadFileRequest设置多个参数。 UploadObjectRequest request = new UploadObjectRequest(bucketName, objectName, localFilename) { // 指定上传的分片大小。 PartSize = 8 * 1024 * 1024, // 指定并发线程数。 ParallelThreadCount = 3, // checkpointDir用于记录本地分片上传结果的文件。上传过程中的进度信息会保存在此文件中,如果某一分片上传失败,再次上传时会根据文件中记录的点继续上传。如果checkpointDir设置为null,断点续传功能不会生效,每次上传失败后都会重新上传。 CheckpointDir = checkpointDir, }; var meta = new ObjectMetadata(); // 在HTTP header中设置标签信息。 string str = UrlEncodeKey("key1") + "=" + UrlEncodeKey("key1") + "&" + UrlEncodeKey("key2") + "=" + UrlEncodeKey("key2"); meta.AddHeader("x-oss-tagging", str); request.Metadata = meta; // 断点续传上传。 client.ResumableUploadObject(request); Console.WriteLine("Resumable upload object:{0} succeeded", objectName); } 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); }
对已上传Object添加或更改对象标签
以下代码用于对已上传Object添加或更改对象标签:
using Aliyun.OSS;
var endpoint = "<yourEndpoint>";
var accessKeyId = "<yourAccessKeyId>";
var accessKeySecret = "<yourAccessKeySecret>";
var bucketName = "<yourBucketName>";
var objectName = "<yourObjectName>";
// 创建OssClient实例。
var client = new OssClient(endpoint, accessKeyId, accessKeySecret);
try
{
// 设置标签信息。
var setRequest = new SetObjectTaggingRequest(bucketName, objectName);
var tag1 = new Tag
{
Key = "project",
Value = "projectone"
};
var tag2 = new Tag
{
Key = "user",
Value = "jsmith"
};
setRequest.AddTag(tag1);
setRequest.AddTag(tag2);
client.SetObjectTagging(setRequest);
Console.WriteLine("set object tagging succeeded");
}
catch (Exception ex)
{
Console.WriteLine("set object tagging failed. {0}", ex.Message);
}
拷贝Object时设置对象标签
拷贝Object时,可以指定如何设置目标Object的对象标签。取值如下:
- Copy(默认值):复制源Object的对象标签到目标Object。
- Replace:忽略源Object的对象标签,直接采用请求中指定的对象标签。
以下分别提供了简单拷贝1 GB以下的Object及分片拷贝1 GB以上的Object时设置对象标签的详细示例。
- 以下代码用于简单拷贝1 GB以下的Object时设置对象标签:
using Aliyun.OSS; using Aliyun.OSS.Common; using System.Text; var endpoint = "<yourEndpoint>"; var accessKeyId = "<yourAccessKeyId>"; var accessKeySecret = "<yourAccessKeySecret>"; var sourceBucket = "<yourSourceBucketName>"; var sourceObject = "<yourSourceObjectName>"; var targetBucket = "<yourDestBucketName>"; var targetObject = "<yourDestObjectName>"; String UrlEncodeKey(String key) { const string CharsetName = "utf-8"; const char separator = '/'; var segments = key.Split(separator); var encodedKey = new StringBuilder(); encodedKey.Append(HttpUtils.EncodeUri(segments[0], CharsetName)); for (var i = 1; i < segments.Length; i++) encodedKey.Append(separator).Append(HttpUtils.EncodeUri(segments[i], CharsetName)); if (key.EndsWith(separator.ToString())) { // String#split ignores trailing empty strings, e.g., "a/b/" will be split as a 2-entries array, // so we have to append all the trailing slash to the uri. foreach (var ch in key) { if (ch == separator) encodedKey.Append(separator); else break; } } return encodedKey.ToString(); } // 创建OssClient实例。 var client = new OssClient(endpoint, accessKeyId, accessKeySecret); try { var metadata = new ObjectMetadata(); metadata.AddHeader("mk1", "mv1"); metadata.AddHeader("mk2", "mv2"); // 在HTTP header中设置标签信息。 string str = UrlEncodeKey("key1") + "=" + UrlEncodeKey("key1") + "&" + UrlEncodeKey("key2") + "=" + UrlEncodeKey("key2"); metadata.AddHeader("x-oss-tagging", str); 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); }
- 以下代码用于分片拷贝1 GB以上的Object时设置对象标签:
using Aliyun.OSS; using System.Text; 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; String UrlEncodeKey(String key) { const string CharsetName = "utf-8"; const char separator = '/'; var segments = key.Split(separator); var encodedKey = new StringBuilder(); encodedKey.Append(HttpUtils.EncodeUri(segments[0], CharsetName)); for (var i = 1; i < segments.Length; i++) encodedKey.Append(separator).Append(HttpUtils.EncodeUri(segments[i], CharsetName)); if (key.EndsWith(separator.ToString())) { // String#split ignores trailing empty strings, e.g., "a/b/" will be split as a 2-entries array, // so we have to append all the trailing slash to the uri. foreach (var ch in key) { if (ch == separator) encodedKey.Append(separator); else break; } } return encodedKey.ToString(); } // 创建OssClient实例。 var client = new OssClient(endpoint, accessKeyId, accessKeySecret); try { // 初始化拷贝任务。您可以通过InitiateMultipartUploadRequest指定目标文件元信息。 var request = new InitiateMultipartUploadRequest(targetBucket, targetObject); var meta = new ObjectMetadata(); // 在HTTP header中设置标签信息。 string str = UrlEncodeKey("key1") + "=" + UrlEncodeKey("key1") + "&" + UrlEncodeKey("key2") + "=" + UrlEncodeKey("key2"); meta.AddHeader("x-oss-tagging", str); request.Metadata = meta; 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); }
为软链接文件设置标签
以下代码用于为软链接文件设置标签:
using Aliyun.OSS;
using System.Text;
var endpoint = "<yourEndpoint>";
var accessKeyId = "<yourAccessKeyId>";
var accessKeySecret = "<yourAccessKeySecret>";
var bucketName = "<yourBucketName>";
var targetObjectName = "<yourTargetObjectName>";
var symlinkObjectName = "<yourSymlinkObjectName>";
var objectContent = "More than just cloud.";
String UrlEncodeKey(String key)
{
const string CharsetName = "utf-8";
const char separator = '/';
var segments = key.Split(separator);
var encodedKey = new StringBuilder();
encodedKey.Append(HttpUtils.EncodeUri(segments[0], CharsetName));
for (var i = 1; i < segments.Length; i++)
encodedKey.Append(separator).Append(HttpUtils.EncodeUri(segments[i], CharsetName));
if (key.EndsWith(separator.ToString()))
{
// String#split ignores trailing empty strings, e.g., "a/b/" will be split as a 2-entries array,
// so we have to append all the trailing slash to the uri.
foreach (var ch in key)
{
if (ch == separator)
encodedKey.Append(separator);
else
break;
}
}
return encodedKey.ToString();
}
// 创建OssClient实例。
var client = new OssClient(endpoint, accessKeyId, accessKeySecret);
try
{
// 上传目标文件。
byte[] binaryData = Encoding.ASCII.GetBytes(objectContent);
MemoryStream requestContent = new MemoryStream(binaryData);
client.PutObject(bucketName, targetObjectName, requestContent);
var meta = new ObjectMetadata();
// 在HTTP header中设置标签信息。
string str = UrlEncodeKey("key1") + "=" + UrlEncodeKey("key1") + "&" + UrlEncodeKey("key2") + "=" + UrlEncodeKey("key2");
meta.AddHeader("x-oss-tagging", str);
var request = new CreateSymlinkRequest(bucketName, symlinkObjectName, targetObjectName);
request.ObjectMetadata = meta;
// 创建软链接。
client.CreateSymlink(request);
// 获取软链接指向的目标文件名称。
var ossSymlink = client.GetSymlink(bucketName, symlinkObjectName);
Console.WriteLine("Target object is {0}", ossSymlink.Target);
}
catch (Exception ex)
{
Console.WriteLine("Failed with error info: {0}", ex.Message);
}