对象元信息是对象的属性描述,包括 HTTP 标准属性(HTTP Header)和用户自定义元数据(User Meta)两种。
通过 TOS .NET SDK 可以添加和修改已经上传对象的元数据信息。TOS 支持携带以下 6 个请求头来修改对象元数据,在下载对象或者 HEAD 对象时,这些值会设置到 HTTP 头域中返回给客户端。请求头如下所示:
名称 | 说明 |
---|---|
Content-Type | 对象类型。 |
Cache-Control | 指定该对象被下载时网页的缓存行为。 |
Expires | RFC2616 中定义的缓存失效时间。 |
Content-Disposition | 对象被下载时的名称。 |
Content-Encoding | 对象被下载时的内容编码类型。 |
Content-Language | 对象被下载时的内容语言格式。 |
x-tos-meta-* | 使用 SDK 设置 Meta 字段时设置的元数据信息。当查询此对象时,元数据将会在返回消息的 Header 中。 |
以下代码用于在上传文件时设置缓存策略、缓存过期时间等元数据信息。
using System; using System.Collections.Generic; using System.IO; using System.Text; using TOS; using TOS.Error; using TOS.Model; namespace ConsoleApp { internal class Program { private static void Main(string[] args) { var ak = Environment.GetEnvironmentVariable("TOS_ACCESS_KEY"); var sk = Environment.GetEnvironmentVariable("TOS_SECRET_KEY"); // endpoint 若没有指定HTTP协议(HTTP/HTTPS),默认使用 HTTPS // Bucket 的 Endpoint,以华北2(北京)为例:https://tos-cn-beijing.volces.com var endpoint = "https://tos-cn-beijing.volces.com"; var region = "cn-beijing"; // 填写 BucketName var bucketName = "*** Provide your bucket name ***"; // 上传对象 Body,以 string 对象为例 var objectContent = "Hello TOS"; // 将文件上传到 example_dir 目录下的 example.txt 文件 var objectKey = "example_dir/example.txt"; // 创建TOSClient实例 var client = TosClientBuilder.Builder().SetAk(ak).SetSk(sk).SetEndpoint(endpoint).SetRegion(region).Build(); try { byte[] binaryData = Encoding.UTF8.GetBytes(objectContent); using (MemoryStream requestContent = new MemoryStream(binaryData)) { // 创建上传文件输入 var putObjectInput = new PutObjectInput() { Bucket = bucketName, Key = objectKey, // 用户自定义元数据信息 Meta = new Dictionary<string, string>() { { "key", "value" } }, // 设置对象类型 ContentType = "text/html", // 设置对象下载时内容语言格式 ContentLanguage = "zh-cn", // 设置缓存策略 CacheControl = "no-store", // 设置缓存过期时间 Expires = DateTime.Now.AddHours(1), // 设置下载内容下载时的名称 ContentDisposition = "example.png", // 设置下载时编码类型 ContentEncoding = "deflate", Content = requestContent }; // 将字符串 “Hello TOS” 上传到指定 example_dir 目录下的 example.txt var putObjectOutput = client.PutObject(putObjectInput); Console.WriteLine("Put object succeeded, ETag: {0} ", putObjectOutput.ETag); } } catch (TosServerException ex) { Console.WriteLine("Put object failed, request id {0}", ex.RequestID); Console.WriteLine("Put object failed, status code {0}", ex.StatusCode); Console.WriteLine("Put object failed, response error code {0}", ex.Code); Console.WriteLine("Put object failed, response error message {0}", ex.Message); } catch (TosClientException ex) { Console.WriteLine("Put object failed, error message {0}", ex.Message); } catch (Exception ex) { Console.WriteLine("Put object failed, {0}", ex.Message); } } } }
以下代码用于在分片上传时设置缓存策略、缓存过期时间等元数据信息。
using System; using System.Collections.Generic; using System.IO; using TOS; using TOS.Error; using TOS.Model; namespace ConsoleApp { internal class Program { private static void Main(string[] args) { var ak = Environment.GetEnvironmentVariable("TOS_ACCESS_KEY"); var sk = Environment.GetEnvironmentVariable("TOS_SECRET_KEY"); // endpoint 若没有指定HTTP协议(HTTP/HTTPS),默认使用 HTTPS // Bucket 的 Endpoint,以华北2(北京)为例:https://tos-cn-beijing.volces.com var endpoint = "https://tos-cn-beijing.volces.com"; var region = "cn-beijing"; // 填写 BucketName var bucketName = "*** Provide your bucket name ***"; // 将文件上传到 example_dir 目录下的 example.txt 文件 var objectKey = "example_dir/example.txt"; // 需要上传的本地文件 var localFileName = "/usr/local/test.txt"; // 创建TOSClient实例 var client = TosClientBuilder.Builder().SetAk(ak).SetSk(sk).SetEndpoint(endpoint).SetRegion(region).Build(); // 初始化分片,指定对象权限为私有,存储类型为低频并设置元数据信息 var uploadID = ""; try { var createMultipartUploadInput = new CreateMultipartUploadInput() { Bucket = bucketName, Key = objectKey, // 用户自定义元数据信息 Meta = new Dictionary<string, string>() { { "key", "value" } }, // 设置对象类型 ContentType = "text/html", // 设置对象下载时内容语言格式 ContentLanguage = "zh-cn", // 设置缓存策略 CacheControl = "no-store", // 设置缓存过期时间 Expires = DateTime.Now.AddHours(1), // 设置下载内容下载时的名称 ContentDisposition = "example.png", // 设置下载时编码类型 ContentEncoding = "deflate", }; var createMultipartUploadOutput = client.CreateMultipartUpload(createMultipartUploadInput); uploadID = createMultipartUploadOutput.UploadID; Console.WriteLine("CreateMultipartUpload succeeded, request id {0}", createMultipartUploadOutput.RequestID); Console.WriteLine("CreateMultipartUpload succeeded, upload id {0}", uploadID); } catch (TosServerException ex) { Console.WriteLine("CreateMultipartUpload failed, request id {0}", ex.RequestID); Console.WriteLine("CreateMultipartUpload failed, status code {0}", ex.StatusCode); Console.WriteLine("CreateMultipartUpload failed, response error code {0}", ex.Code); Console.WriteLine("CreateMultipartUpload failed, response error message {0}", ex.Message); } catch (TosClientException ex) { Console.WriteLine("CreateMultipartUpload failed, error message {0}", ex.Message); } catch (Exception ex) { Console.WriteLine("CreateMultipartUpload failed, {0}", ex.Message); } // part size 大小设置为 20M Int64 partSize = 20 * 1024 * 1024; // 计算分片信息 var fi = new FileInfo(localFileName); var fileSize = fi.Length; var partCount = fileSize / partSize; if (fileSize % partSize != 0) { partCount++; } var parts = new UploadedPart[partCount]; // 开始分片上传 try { using (var fileStream = File.Open(localFileName, FileMode.Open, FileAccess.Read)) { for (var i = 0; i < partCount; i++) { var offset = partSize * i; // 定位到本次上传的起始位置。 fileStream.Seek(offset, 0); // 计算本次上传的分片大小,最后一片为剩余的数据大小。 var contentSize = (partSize < fileSize - offset) ? partSize : (fileSize - offset); var UploadPartInput = new UploadPartInput() { Bucket = bucketName, Key = objectKey, UploadID = uploadID, // partNumber 编号从 1 开始 PartNumber = i + 1, Content = fileStream, ContentLength = contentSize }; var uploadPartOutput = client.UploadPart(UploadPartInput); parts[i] = new UploadedPart { PartNumber = i + 1, ETag = uploadPartOutput.ETag }; Console.WriteLine("UploadPart succeeded, request id {0}", uploadPartOutput.RequestID); } } } catch (TosServerException ex) { Console.WriteLine("UploadPart failed, request id {0}", ex.RequestID); Console.WriteLine("UploadPart failed, status code {0}", ex.StatusCode); Console.WriteLine("UploadPart failed, response error code {0}", ex.Code); Console.WriteLine("UploadPart failed, response error message {0}", ex.Message); } catch (TosClientException ex) { Console.WriteLine("UploadPart failed, error message {0}", ex.Message); } catch (Exception ex) { Console.WriteLine("UploadPart failed, {0}", ex.Message); } // 合并分片 try { var completeMultipartUploadInput = new CompleteMultipartUploadInput() { Bucket = bucketName, Key = objectKey, UploadID = uploadID, Parts = parts }; var completeMultipartUploadOutput = client.CompleteMultipartUpload(completeMultipartUploadInput); Console.WriteLine("CompleteMultipartUpload succeeded, request id {0}", completeMultipartUploadOutput.RequestID); } catch (TosServerException ex) { Console.WriteLine("CompleteMultipartUpload failed, request id {0}", ex.RequestID); Console.WriteLine("CompleteMultipartUpload failed, status code {0}", ex.StatusCode); Console.WriteLine("CompleteMultipartUpload failed, response error code {0}", ex.Code); Console.WriteLine("CompleteMultipartUpload failed, response error message {0}", ex.Message); } catch (TosClientException ex) { Console.WriteLine("CompleteMultipartUpload failed, error message {0}", ex.Message); } catch (Exception ex) { Console.WriteLine("CompleteMultipartUpload failed, {0}", ex.Message); } } } }
以下代码用于通过 SetObjectMeta 接口更新对象缓存策略、缓存过期时间等元数据信息。
using System; using System.Collections.Generic; using TOS; using TOS.Error; using TOS.Model; namespace ConsoleApp { internal class Program { private static void Main(string[] args) { var ak = Environment.GetEnvironmentVariable("TOS_ACCESS_KEY"); var sk = Environment.GetEnvironmentVariable("TOS_SECRET_KEY"); // endpoint 若没有指定HTTP协议(HTTP/HTTPS),默认使用 HTTPS // Bucket 的 Endpoint,以华北2(北京)为例:https://tos-cn-beijing.volces.com var endpoint = "https://tos-cn-beijing.volces.com"; var region = "cn-beijing"; // 填写 BucketName var bucketName = "*** Provide your bucket name ***"; // 填写对象名 var objectKey = "*** Provide your object key ***"; // 创建TOSClient实例 var client = TosClientBuilder.Builder().SetAk(ak).SetSk(sk).SetEndpoint(endpoint).SetRegion(region).Build(); try { // 设置对象元数据信息 var setObjectMetaInput = new SetObjectMetaInput() { Bucket = bucketName, Key = objectKey, // 用户自定义元数据信息 Meta = new Dictionary<string, string>() { { "key", "value" } }, // 设置对象类型 ContentType = "text/html", // 设置对象下载时内容语言格式 ContentLanguage = "zh-cn", // 设置缓存策略 CacheControl = "no-store", // 设置缓存过期时间 Expires = DateTime.Now.AddHours(1), // 设置下载内容下载时的名称 ContentDisposition = "example.png", // 设置下载时编码类型 ContentEncoding = "deflate", }; var setObjectMetaOutput = client.SetObjectMeta(setObjectMetaInput); Console.WriteLine("Set object meta succeeded, request id: {0} ", setObjectMetaOutput.RequestID); } catch (TosServerException ex) { Console.WriteLine("Set object meta failed, request id {0}", ex.RequestID); Console.WriteLine("Set object meta failed, status code {0}", ex.StatusCode); Console.WriteLine("Set object meta failed, response error code {0}", ex.Code); Console.WriteLine("Set object meta failed, response error message {0}", ex.Message); } catch (TosClientException ex) { Console.WriteLine("Set object meta failed, error message {0}", ex.Message); } catch (Exception ex) { Console.WriteLine("Set object meta failed, {0}", ex.Message); } } } }
注意
获取对象元数据之前,您需要确保账号必须拥有 tos:GetObject 权限,具体操作,请参见 IAM策略概述。
以下代码用于查询对象元数据信息,以及判断对象是否存在,如果对象不存在,则会返回报错信息。
using System; using TOS; using TOS.Error; using TOS.Model; namespace ConsoleApp { internal class Program { private static void Main(string[] args) { var ak = Environment.GetEnvironmentVariable("TOS_ACCESS_KEY"); var sk = Environment.GetEnvironmentVariable("TOS_SECRET_KEY"); // endpoint 若没有指定HTTP协议(HTTP/HTTPS),默认使用 HTTPS // Bucket 的 Endpoint,以华北2(北京)为例:https://tos-cn-beijing.volces.com var endpoint = "https://tos-cn-beijing.volces.com"; var region = "cn-beijing"; // 填写 BucketName var bucketName = "*** Provide your bucket name ***"; // 填写对象名 var objectKey = "*** Provide your object key ***"; // 创建TOSClient实例 var client = TosClientBuilder.Builder().SetAk(ak).SetSk(sk).SetEndpoint(endpoint).SetRegion(region).Build(); try { var headObjectInput = new HeadObjectInput() { Bucket = bucketName, Key = objectKey, }; var headObjectOutput = client.HeadObject(headObjectInput); Console.WriteLine("HeadObject succeeded, Request ID: {0} ", headObjectOutput.RequestID); // 查看内容语言格式 Console.WriteLine("HeadObject succeeded, Response ContentLanguage: {0} ", headObjectOutput.ContentLanguage); // 查看下载时的名称 Console.WriteLine("HeadObject succeeded, Response ContentDisposition: {0} ", headObjectOutput.ContentDisposition); // 查看编码类型 Console.WriteLine("HeadObject succeeded, Response ContentEncoding: {0} ", headObjectOutput.ContentEncoding); // 查看缓存策略 Console.WriteLine("HeadObject succeeded, Response CacheControl: {0} ", headObjectOutput.CacheControl); // 查看对象类型 Console.WriteLine("HeadObject succeeded, Response ContentType: {0} ", headObjectOutput.ContentType); // 查看缓存过期时间 Console.WriteLine("HeadObject succeeded, Response Expires: {0} ", headObjectOutput.Expires); } catch (TosServerException ex) { // 判断对象是否存在 if (ex.StatusCode == 404) { Console.WriteLine("Object not found"); } else { Console.WriteLine("HeadObject failed, Request ID {0}", ex.RequestID); Console.WriteLine("HeadObject failed, Status Code {0}", ex.StatusCode); Console.WriteLine("HeadObject failed, Response Error Code {0}", ex.Code); Console.WriteLine("HeadObject failed, Response Error Message {0}", ex.Message); } } catch (TosClientException ex) { Console.WriteLine("HeadObject failed, Error Message {0}", ex.Message); } catch (Exception ex) { Console.WriteLine("HeadObject failed, {0}", ex.Message); } } } }
关于设置对象元数据的 API 接口详细介绍,请参见 SetObjectMeta。