Object管理
上传Object
最简单的上传
-
基本流程
- 创建一个BosClient类的实例。
- 调用BosClient.PutObject()方法。调用该方法时您需要提供Bucket名称、ObjectKey和Object的内容。可以通过如下四种方式上传Object:文件、数据流、二进制串和字符串的形式。
-
示例代码
C#1public void PutObject(BosClient client, String bucketName, String objectKey, byte[] byte1, String string1) 2{ 3 4 // 获取指定文件 5 FileInfo file = new FileInfo(<FilePath>); //指定文件路径 6 7 // 以文件形式上传Object 8 PutObjectResponse putObjectFromFileResponse = client.PutObject(bucketName, objectKey, file); 9 10 // 获取数据流 11 Stream inputStream = file.OpenRead(); 12 13 // 以数据流形式上传Object 14 PutObjectResponse putObjectResponseFromInputStream = client.PutObject(bucketName, objectKey, inputStream); 15 16 // 以二进制串上传Object 17 PutObjectResponse putObjectResponseFromByte = client.PutObject(bucketName, objectKey,Encoding.Default.GetBytes("sampledata")); 18 19 // 以字符串上传Object 20 PutObjectResponse putObjectResponseFromString = client.PutObject(bucketName, objectKey, "sampledata"); 21 22 // 打印ETag 23 Console.WriteLine(putObjectFromFileResponse.ETAG); 24 25}
说明:Object以文件的形式上传到BOS中,putObject函数支持不超过5GB的Object上传。在putObject请求处理成功后,BOS会在Header中返回Object的ETag作为文件标识。
-
完整示例
请参考完整示例。
设定Object的Http Header
BOS支持您在上传object时设定Http Header。
-
基本流程
- 创建一个BosClient类的实例。
- 调用BosClient.PutObject()时候,您还可以传入一个ObjectMetadata对象,该对象可以设置自定义的Http Header。
-
示例代码
C#1// 初始化上传输入流 2ObjectMetadata meta = new ObjectMetadata(); 3 4// 设置ContentLength大小 5meta.ContentLength = <Length>; 6 7// 设置ContentType 8meta.ContentType = "application/json"; 9 10client.PutObject(bucketName, objectKey, <SampleData>, meta);
-
完整示例
请参考完整示例。
用户自定义元数据
-
基本流程
- 创建一个BosClient类的实例。
- 调用BosClient.PutObject()时候,您还可以传入一个ObjectMetadata对象,该对象支持用户自定义元数据来对Object进行描述。
-
示例代码
C#1// 设置自定义元数据name的值为my-data 2meta.UserMetadata["name"] = "my-data"; 3 4// 上传Object 5client.PutObject(bucketName, objectKey, <SampleData>, meta);
说明:在上面代码中,用户自定义了一个名字为”name”,值为”my-data”的元数据。当用户下载此Object的时候,此元数据也可以一并得到。一个Object可以有多个类似的参数,但所有的User Meta总大小不能超过2KB。
-
完整示例
请参考完整示例。
完整示例
下面示例代码演示了简单上传Object、设定Object的Http Header和用户自定义元数据的完整过程:
1using System;
2using System.Collections.Generic;
3using System.IO;
4using System.Linq;
5using System.Text;
6using BaiduBce;
7using BaiduBce.Auth;
8using BaiduBce.Services.Bos;
9using BaiduBce.Services.Bos.Model;
10
11namespace DotnetSample
12{
13 internal class PutObjectSample
14 {
15 private static void Main(string[] args)
16 {
17 BosClient client = GenerateBosClient();
18 const string bucketName = <BucketName>; //您的Bucket名称
19 const string objectNameFile = <ObjectNameFile>; //文件形式上传的Object名称
20 const string objectNameStream = <ObjectNameStream>; //数据流形式上传的Object名称
21 const string objectNameString = <ObjectNameString>; //字符串形式上传的Object名称
22 const string objectNameByte = <ObjectNameByte>; //二进制形式上传的Object名称
23
24 // 新建一个Bucket
25 client.CreateBucket(bucketName); //指定Bucket名称
26
27 // 设置待上传的文件名
28 const string fileName = "d:\\sample.txt";
29
30 // 以文件形式上传Object
31 PutObjectResponse putObjectFromFileResponse = client.PutObject(bucketName, objectNameFile,
32 new FileInfo(fileName));
33
34 // 以数据流形式上传Object
35 PutObjectResponse putObjectResponseFromInputStream = client.PutObject(bucketName, objectNameStream,
36 new FileInfo(fileName).OpenRead());
37
38 // 以二进制串上传Object
39 PutObjectResponse putObjectResponseFromByte = client.PutObject(bucketName, objectNameByte,
40 Encoding.Default.GetBytes("sampledata"));
41
42 // 以字符串上传Object
43 PutObjectResponse putObjectResponseFromString = client.PutObject(bucketName, objectNameString,
44 "sampledata");
45
46 // 打印四种方式的ETag。示例中,文件方式和stream方式的ETag相等,string方式和byte方式的ETag相等
47 Console.WriteLine(putObjectFromFileResponse.ETAG);
48 Console.WriteLine(putObjectResponseFromInputStream.ETAG);
49 Console.WriteLine(putObjectResponseFromByte.ETAG);
50 Console.WriteLine(putObjectResponseFromString.ETAG);
51
52 // 上传Object并设置自定义参数
53 ObjectMetadata meta = new ObjectMetadata();
54 // 设置ContentLength大小
55 meta.ContentLength = 10;
56 // 设置ContentType
57 meta.ContentType = "application/json";
58 // 设置自定义元数据name的值为my-data
59 meta.UserMetadata["name"] = "my-data";
60 // 上传Object并打印ETag
61 putObjectResponseFromString = client.PutObject(bucketName, objectNameString, "sampledata", meta);
62 Console.WriteLine(putObjectResponseFromString.ETAG);
63 }
64
65 private static BosClient GenerateBosClient()
66 {
67 const string accessKeyId = <AccessKeyID>; // 您的Access Key ID
68 const string secretAccessKey = <SecretAccessKey>; // 您的Secret Access Key
69 const string endpoint = "https://bj.bcebos.com"; // 指定BOS服务域名
70
71 // 初始化一个BosClient
72 BceClientConfiguration config = new BceClientConfiguration();
73 config.Credentials = new DefaultBceCredentials(accessKeyId, secretAccessKey);
74 config.Endpoint = endpoint;
75
76 return new BosClient(config);
77 }
78 }
79}
查看Bucket中的Object
简单查询
查看Bucket中Object列表。
-
基本流程
- 创建一个BOSClient类的实例。
- 调用BOSClient.ListObjects()方法。调用该方法时你需要提供Bucket名称。
-
示例代码
C#1public void ListObjects(BosClient client, string bucketName) 2{ 3 4 // 获取指定Bucket下的所有Object信息 5 ListObjectsResponse listObjectsResponse = client.ListObjects(bucketName); 6 7 // 遍历所有Object 8 foreach (BosObjectSummary objectSummary in listObjectsResponse.Contents) 9 { 10 Console.WriteLine("ObjectKey: " + objectSummary.Key); 11 } 12 13}
说明: listObjects( )方法返回ListObjectsResponse对象,ListObjectsResponse对象包含了此次listObject请求的返回结果。用户可以通过ListObjectsResponse中的getContents方法获取所有Object的描述信息。
- 默认情况下,如果Bucket中的Object数量大于1000,则只会返回1000个Object,并且返回结果中IsTruncated值为True,并返回NextMarker做为下次读取的起点。
- 若想获取更多的Object,可以使用Marker参数分次读取,请参考扩展查询。
-
完整示例
请参考完整示例。
扩展查询
用户可以通过设置ListObjectsRequest参数来完成更多扩展查询操作设置。ListObjectsRequest中可以设置的扩展参数如下:
参数名称 | 说明 | 默认值 |
---|---|---|
MaxKeys | 设定此次返回Object的最大个数,不可超过1000。 | 1000 |
Prefix | 设定objectKey的前缀,前缀是指objectKey包含并以Prefix的值作为开始。 通常与Delimiter配合在查询模拟文件夹中使用。 |
- |
Delimiter | 是一个分隔符,用来对objectKey进行分层。 通常与Prefix配合在查询模拟文件夹中使用。 从Prefix开始到第一次出现Delimiter字符之间的objectKey称为:CommonPrefixes。 |
- |
Marker | 是一个字符串,用来设定返回结果的起始位置。 设定Marker值之后,返回的Object会从Marker值之后按字母排序开始返回。 |
- |
-
基本流程
- 创建一个BOSClient类的实例。
- 您也可以构造一个ListObjectsRequest来调用ListObjects(),ListObjectsRequest等方法,实现更多的扩展查询操作。
-
示例代码
C#1// 构造ListObjectsRequest请求 2ListObjectsRequest listObjectsRequest = new ListObjectsRequest() {BucketName = bucketName}; 3 4// 设置参数 5listObjectsRequest.Delimiter=<Delimiter>; 6listObjectsRequest.Marker=<Marker>; 7 8ListObjectsResponse listObjectsResponse = client.ListObjects(listObjectsRequest);
说明:
上面代码中调用了
listObjects
中的一个重载方法,通过传入ListObjectsRequest
来完成请求。 -
完整示例
请参考完整示例。
查询模拟文件夹
由于BOS本身是一个(<Key>,<Value>
)的存储系统,所以原则上并不会存在“文件夹”的概念,但您可以通过 Delimiter
和 Prefix
参数的配合进行文件夹功能模拟。
假设Bucket中有5个文件:bos.jpg,fun/,fun/test.jpg,fun/movie/001.avi,fun/movie/007.avi,可以把 “/” 符号作为分隔符模拟文件夹。
递归列出模拟文件夹下所有文件
可以通过设置 Prefix
参数来获取某个目录下所有的文件:
1// 构造ListObjectsRequest请求
2ListObjectsRequest listObjectsRequest = new ListObjectsRequest() {BucketName = bucketName};
3
4// 递归列出fun目录下的所有文件
5listObjectsRequest.Prefix = "fun/";
6
7// List Objects
8ListObjectsResponse listObjectsResponse = client.ListObjects(listObjectsRequest);
9
10// 遍历所有Object
11Console.WriteLine("Objects:");
12foreach (BosObjectSummary objectSummary in listObjectsResponse.Contents)
13{
14 Console.WriteLine("ObjectKey: " + objectSummary.Key);
15}
输出:
1Objects:
2fun/
3fun/movie/001.avi
4fun/movie/007.avi
5fun/test.jpg
查看模拟文件夹下的文件和子文件夹
在 Prefix
和 Delimiter
结合的情况下,可以列出模拟文件夹下的文件和子文件夹:
1// 构造ListObjectsRequest请求
2ListObjectsRequest listObjectsRequest = new ListObjectsRequest() {BucketName = bucketName};
3
4// "/" 为文件夹的分隔符
5listObjectsRequest.Delimiter = "/";
6
7// 列出fun目录下的所有文件和文件夹
8listObjectsRequest.Prefix = "fun/";
9
10// List Objects
11ListObjectsResponse listObjectsResponse = client.ListObjects(listObjectsRequest);
12
13// 遍历所有Object,相当于获取fun目录下的所有文件
14Console.WriteLine("Objects:");
15foreach (BosObjectSummary objectSummary in listObjectsResponse.Contents)
16{
17 Console.WriteLine("ObjectKey: " + objectSummary.Key);
18}
19
20// 遍历所有CommonPrefix,相当于获取fun目录下的所有文件夹
21Console.WriteLine("\nCommonPrefixs:");
22foreach (ObjectPrefix objectPrefix in listObjectsResponse.CommonPrefixes)
23{
24 Console.WriteLine(objectPrefix.Prefix);
25}
输出:
1Objects:
2fun/
3fun/test.jpg
4
5CommonPrefixs:
6fun/movie/
说明:
返回的结果中,
Objects
的列表中给出的是fun文件夹下的文件。而CommonPrefixs
的列表中给出的是fun文件夹下的所有子文件夹。可以看出fun/movie/001.avi
,fun/movie/007.avi
两个文件并没有被列出来,因为它们属于fun
文件夹下的movie
子文件夹下的文件。
-
完整示例
请参考完整示例。
完整示例
下面示例代码演示了Object的简单查询、使用nextmarker分次查询、扩展查询、查询模拟文件夹的完整过程:
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using BaiduBce;
6using BaiduBce.Auth;
7using BaiduBce.Services.Bos;
8using BaiduBce.Services.Bos.Model;
9
10namespace DotnetSample
11{
12 internal class ListObjectsSample
13 {
14 private static void Main(string[] args)
15 {
16 BosClient client = GenerateBosClient();
17 const string bucketName = <BucketName>; //您的Bucket名称
18
19 // 新建一个Bucket
20 client.CreateBucket(bucketName);
21
22 // 创建bos.jpg,fun/,fun/test.jpg,fun/movie/001.avi,fun/movie/007.avi五个文件
23 client.PutObject(bucketName, "bos.jpg", "sampledata");
24 client.PutObject(bucketName, "fun/", "sampledata");
25 client.PutObject(bucketName, "fun/test.jpg", "sampledata");
26 client.PutObject(bucketName, "fun/movie/001.avi", "sampledata");
27 client.PutObject(bucketName, "fun/movie/007.avi", "sampledata");
28
29 // 构造ListObjectsRequest请求
30 ListObjectsRequest listObjectsRequest = new ListObjectsRequest() { BucketName = bucketName };
31
32 // 1. 简单查询,列出Bucket下所有文件
33 ListObjectsResponse listObjectsResponse = client.ListObjects(listObjectsRequest);
34
35 // 输出:
36 // Objects:
37 // bos.jpg
38 // fun/
39 // fun/movie/001.avi
40 // fun/movie/007.avi
41 // fun/test.jpg
42
43 Console.WriteLine("Objects:");
44 foreach (BosObjectSummary objectSummary in listObjectsResponse.Contents)
45 {
46 Console.WriteLine("ObjectKey: " + objectSummary.Key);
47 }
48
49 // 2. 使用NextMarker分次列出所有文件
50 listObjectsRequest.MaxKeys = 2;
51 listObjectsResponse = client.ListObjects(listObjectsRequest);
52
53 // 输出:
54 // Objects:
55 // bos.jpg
56 // fun/
57 // fun/movie/001.avi
58 // fun/movie/007.avi
59 // fun/test.jpg
60 Console.WriteLine("Objects:");
61 while (listObjectsResponse.IsTruncated)
62 {
63 foreach (BosObjectSummary objectSummary in listObjectsResponse.Contents)
64 {
65 Console.WriteLine("ObjectKey: " + objectSummary.Key);
66 }
67 listObjectsResponse = client.ListNextBatchOfObjects(listObjectsResponse);
68 }
69 foreach (BosObjectSummary objectSummary in listObjectsResponse.Contents)
70 {
71 Console.WriteLine("ObjectKey: " + objectSummary.Key);
72 }
73
74 // 3. 递归列出“fun/”下所有文件和子文件夹
75 listObjectsRequest.Prefix = "fun/";
76 listObjectsResponse = client.ListObjects(listObjectsRequest);
77
78 // 输出:
79 // Objects:
80 // fun/
81 // fun/movie/001.avi
82 // fun/movie/007.avi
83 // fun/test.jpg
84
85 Console.WriteLine("Objects:");
86 foreach (BosObjectSummary objectSummary in listObjectsResponse.Contents)
87 {
88 Console.WriteLine("ObjectKey: " + objectSummary.Key);
89 }
90
91 // 4. 列出“fun”下的文件和子文件夹
92 listObjectsRequest.Delimiter = "/";
93 listObjectsResponse = client.ListObjects(listObjectsRequest);
94
95 // 输出:
96 // Objects:
97 // fun/
98 // fun/test.jpg
99
100 Console.WriteLine("Objects:");
101 foreach (BosObjectSummary objectSummary in listObjectsResponse.Contents)
102 {
103 Console.WriteLine("ObjectKey: " + objectSummary.Key);
104 }
105
106 // 遍历所有CommonPrefix,相当于获取fun目录下的所有子文件夹
107 // 输出:
108 // CommonPrefixs:
109 // fun/movie
110
111 Console.WriteLine("\nCommonPrefixs:");
112 foreach (ObjectPrefix objectPrefix in listObjectsResponse.CommonPrefixes)
113 {
114 Console.WriteLine(objectPrefix.Prefix);
115 }
116 }
117
118 private static BosClient GenerateBosClient()
119 {
120 const string accessKeyId = <AccessKeyID>; // 您的Access Key ID
121 const string secretAccessKey = <SecretAccessKey>; // 您的Secret Access Key
122 const string endpoint = "https://bj.bcebos.com"; // 指定BOS服务域名
123
124 // 初始化一个BosClient
125 BceClientConfiguration config = new BceClientConfiguration();
126 config.Credentials = new DefaultBceCredentials(accessKeyId, secretAccessKey);
127 config.Endpoint = endpoint;
128
129 return new BosClient(config);
130 }
131 }
132}
获取Object
简单的获取Object
-
基本流程
- 创建BosClient类的实例。
- 执行BosClient.GetObject()方法,会返回指定的BosObject。
- 将BosObject读到流中,然后对流进行操作。
-
示例代码
C#1public void GetObject(BosClient client, String bucketName, String objectKey) 2{ 3 4 // 获取Object,返回结果为BosObject对象 5 BosObject bosObject = client.GetObject(bucketName, objectKey); 6 7 // 获取ObjectMeta 8 ObjectMetadata meta = bosObject.ObjectMetadata; 9 10 // 获取Object的输入流 11 Stream objectContent = bosObject.ObjectContent; 12 13 // 处理Object 14 ... 15 16 // 关闭流 17 objectContent.Close(); 18}
注意:
- BosObject中包含了Object的各种信息,包含Object所在的Bucket、Object的名称、MetaData以及一个输入流,
- 用户可以通过操作输入流将Object的内容读取到文件或者内存中。
- ObjectMetadata中包含了Object上传时定义的ETag,Http Header以及自定义的元数据。
- 通过BosObject的getObjectContent()方法,还可以获取返回Object的输入流,用户可以读取这个输入流来对Object的内容进行操作。
-
完整示例
请参考完整示例。
通过GetObjectRequest获取Object
为了实现更多的功能,可以通过使用GetObjectRequest来获取Object。
-
基本流程
- 创建GetObjectRequest类的实例。
- 对GetObjectRequest执行setRange( ),获取Object中所需的字节数据。
- 执行GetObject( )操作。
-
示例代码
C#1// 新建GetObjectRequest 2 GetObjectRequest getObjectRequest = new GetObjectRequest() {BucketName = bucketName, Key = objectKey}; 3 4// 获取0~100字节范围内的数据 5getObjectRequest.SetRange(0, 100); 6 7// 获取Object,返回结果为BosObject对象 8BosObject bosObject = client.GetObject(getObjectRequest);
说明:通过getObjectRequest的setRange( )方法可以设置返回Object的范围。用户可以用此功能实现文件的分段下载和断点续传。
-
完整示例
请参考完整示例。
直接下载Object到指定路径
用户可以通过如下代码直接将Object下载到指定路径。
-
基本流程
- 创建GetObjectRequest类的实例。
- 执行client.getObject( )操作。
- Object可以直接下载到指定路径。
-
示例代码
C#1// 新建GetObjectRequest 2GetObjectRequest getObjectRequest = new GetObjectRequest() {BucketName = bucketName, Key = objectKey}; 3 4// 下载Object到文件 5ObjectMetadata objectMetadata = client.GetObject(getObjectRequest, new FileInfo("d:\\sample.txt"));
说明:当使用上面方法将Object直接下载到指定路径时,方法会返回ObjectMetadata对象。
-
完整示例
请参考完整示例。
只获取ObjectMetadata
通过 getObjectMetadata() 方法可以只获取ObjectMetadata而不获取Object的实体。
-
示例代码
C#1ObjectMetadata objectMetadata = client.GetObjectMetadata(bucketName, objectKey);
-
完整示例
请参考完整示例。
获取Object的URL
您可以通过如下代码获取指定Object的URL,该功能通常用于您将Object的URL临时分享给其他用户的场景。
-
基本流程
- 创建一个BosClient类的实例。
- 调用BosClient.GeneratePresignedUrl()方法,在调用该方法时您需要提供Bucket名称,object名称,过期时间等参数。
- 返回一个Object的URL。
-
示例代码
C#1public string GeneratePresignedUrl(BosClient client, string bucketName, string objectKey, 2 int expirationInSeconds) 3{ 4 //指定用户需要获取的Object所在的Bucket名称、该Object名称、时间戳、URL的有效时长 5 Uri url = client.GeneratePresignedUrl(bucketName, objectKey, expirationInSeconds); 6 return url.AbsoluteUri; 7}
说明:
ExpirationInSeconds
为指定的URL有效时长,时间从当前时间算起,为可选参数,不配置时系统默认值为1800秒。如果要设置为永久不失效的时间,可以将ExpirationInSeconds
参数设置为 -1,不可设置为其他负数。 -
完整示例
请参考完整示例。
完整示例
下面示例代码演示了简单获取Object、通过GetObjectRequest获取Object、直接下载Object到指定路径、只获取ObjectMetadata以及获取Object的URL的完整过程:
1using System;
2using System.Collections.Generic;
3using System.IO;
4using System.Linq;
5using System.Text;
6using BaiduBce;
7using BaiduBce.Auth;
8using BaiduBce.Services.Bos;
9using BaiduBce.Services.Bos.Model;
10
11namespace DotnetSample
12{
13 internal class GetObjectsSample
14 {
15 private static void Main(string[] args)
16 {
17 BosClient client = GenerateBosClient();
18 const string bucketName = <BucketName>; //您的Bucket名称
19
20 // 初始化,创建Bucket和Object
21 client.CreateBucket(bucketName);
22 string objectName = <ObjectKey>;
23 client.PutObject(bucketName, objectName, <SampleData>);
24
25 // 获取BosObject对象并通过BosObject的输入流获取内容
26 BosObject bosObject = client.GetObject(bucketName, objectName);
27 Stream objectContent = bosObject.ObjectContent;
28 string content = new StreamReader(objectContent).ReadToEnd();
29 Console.WriteLine(content); // 您传入的<SampleData>
30
31 // 通过GetObjectRequest只获取部分数据
32 GetObjectRequest getObjectRequest = new GetObjectRequest() {BucketName = bucketName, Key = objectName};
33 getObjectRequest.SetRange(0, 5);
34 bosObject = client.GetObject(getObjectRequest);
35 objectContent = bosObject.ObjectContent;
36 content = new StreamReader(objectContent).ReadToEnd();
37 Console.WriteLine(content); // 您传入的<SampleData>
38
39 // 直接通过GetObjectContent获取byte[]内容
40 byte[] bytes = client.GetObjectContent(bucketName, objectName);
41 content = Encoding.Default.GetString(bytes);
42 Console.WriteLine(content); // 您传入的<SampleData>
43
44 // 将Object内容下载到文件
45 FileInfo fileInfo = new FileInfo("my file path and name");
46 client.GetObject(bucketName, objectName,fileInfo );
47 content = File.ReadAllText(fileInfo.FullName);
48 Console.WriteLine(content); // 您传入的<SampleData>
49
50 // 只获取object的meta,不获取内容
51 ObjectMetadata objectMetadata = client.GetObjectMetadata(bucketName, objectName);
52 Console.WriteLine(objectMetadata.ContentLength);
53
54 Console.ReadKey();
55
56 // 生成url,并通过该url直接下载和打印对象内容
57 string url = client.GeneratePresignedUrl(bucketName, objectName, 60).AbsoluteUri;
58 using (WebClient webClient = new WebClient())
59 {
60 using (Stream stream = webClient.OpenRead(url))
61 using (StreamReader streamReader = new StreamReader(stream))
62 {
63 string response = streamReader.ReadToEnd();
64 Console.WriteLine(response); // 您传入的<SampleData>
65 }
66 }
67 }
68
69 private static BosClient GenerateBosClient()
70 {
71 const string accessKeyId = <AccessKeyID>; // 您的Access Key ID
72 const string secretAccessKey = <SecretAccessKey>; // 您的Secret Access Key
73 const string endpoint = "https://bj.bcebos.com"; // 指定BOS服务域名
74
75 // 初始化一个BosClient
76 BceClientConfiguration config = new BceClientConfiguration();
77 config.Credentials = new DefaultBceCredentials(accessKeyId, secretAccessKey);
78 config.Endpoint = endpoint;
79
80 return new BosClient(config);
81 }
82 }
83}
删除Object
-
基本流程
- 创建一个BosClient类的实例。
- 调用BosClient.DeleteObject()方法。在调用该方法时你需要提供Bucket名称,Object名称等参数。
-
示例代码
C#1public void DeleteObject(BosClient client, string bucketName, string objectKey) 2{ 3// 删除Object 4client.DeleteObject(bucketName, objectKey); 5}
-
完整示例
C#1using System; 2using System.Collections.Generic; 3using System.IO; 4using System.Linq; 5using System.Net; 6using System.Text; 7using BaiduBce; 8using BaiduBce.Auth; 9using BaiduBce.Services.Bos; 10using BaiduBce.Services.Bos.Model; 11 12namespace DotnetSample 13{ 14 internal class DeleteObjectSample 15 { 16 private static void Main(string[] args) 17 { 18 BosClient client = GenerateBosClient(); 19 const string bucketName = <BucketName>; //指定Bucket名称 20 21 // 初始化:创建示例Bucket和Object 22 client.CreateBucket(bucketName); 23 string objectName = <ObjectKey>; 24 client.PutObject(bucketName, objectName, <Sampledata>); 25 26 // 删除Object 27 client.DeleteObject(bucketName, objectName); 28 } 29 30 private static BosClient GenerateBosClient() 31 { 32 const string accessKeyId = <AccessKeyID>; // 您的Access Key ID 33 const string secretAccessKey = <SecretAccessKey>; // 您的Secret Access Key 34 const string endpoint = "https://bj.bcebos.com"; // 指定BOS服务域名 35 36 // 初始化一个BosClient 37 BceClientConfiguration config = new BceClientConfiguration(); 38 config.Credentials = new DefaultBceCredentials(accessKeyId, secretAccessKey); 39 config.Endpoint = endpoint; 40 41 return new BosClient(config); 42 } 43 } 44}
拷贝Object
简单拷贝Object
-
基本流程
- 创建BosClient 类的实例。
- 执行BosClient.copyObject( )方法。
-
示例代码
C#1public void CopyObject(BosClient client, String srcBucketName, String srcKey, String destBucketName, 2String destKey) 3{ 4 // 拷贝Object 5 CopyObjectResponse copyObjectResponse = client.CopyObject(srcBucketName, srcKey, destBucketName, destKey); 6 7 // 打印结果 8 Console.WriteLine("ETag: " + copyObjectResponse.ETag + " LastModified: " + copyObjectResponse.LastModified); 9}
说明:copyObject 方法返回一个
CopyObjectResponse
对象,该对象中包含了新Object的ETag和修改时间。 -
完整示例
请参考完整示例。
通过CopyObjectRequest拷贝Object
您也可以通过 CopyObjectRequest
实现Object的拷贝。该功能一般用于如下场景:
- Copy一个Object但重新设置meta。
- 重置某个现有Object的meta(把Src和Des设置为同一个Object)。
-
基本流程
- 创建CopyObjectRequest类的实例,传入
<SrcBucketName>
,<SrcKey>
,<DestBucketName>
,<DestKey>
参数。 - 创建ObjectMetadata类的实例。
- 创建CopyObjectRequest类的实例,传入
-
示例代码
C#1// 初始化BosClient 2BosClient client = ...; 3 4// 创建CopyObjectRequest对象 5CopyObjectRequest copyObjectRequest = new CopyObjectRequest() 6{ 7 SourceBucketName = srcBucketName, 8 SourceKey = srcKey, 9 BucketName = destBucketName, 10 Key = destKey 11}; 12 13// 设置新的Metadata 14Dictionary<String, String> userMetadata = new Dictionary<String, String>(); 15userMetadata["usermetakey"] = "usermetavalue"; 16ObjectMetadata objectMetadata = new ObjectMetadata() 17{ 18 UserMetadata = userMetadata 19}; 20copyObjectRequest.NewObjectMetadata = objectMetadata; 21 22// 复制Object并打印新的ETag 23CopyObjectResponse copyObjectResponse = client.CopyObject(copyObjectRequest); 24Console.WriteLine("ETag: " + copyObjectResponse.ETag + " LastModified: " + copyObjectResponse.LastModified);
说明:
CopyObjectRequest
允许用户修改目的Object的ObjectMeta,同时也提供MatchingETagConstraints
参数的设定。 -
完整示例
请参考完整示例。
完整示例
下面示例代码演示了简单拷贝Object和通过CopyObjectRequest拷贝Object的完整过程:
1using System;
2using System.Collections.Generic;
3using System.IO;
4using System.Linq;
5using System.Net;
6using System.Text;
7using BaiduBce;
8using BaiduBce.Auth;
9using BaiduBce.Services.Bos;
10using BaiduBce.Services.Bos.Model;
11
12namespace DotnetSample
13{
14 internal class CopyObjectSample
15 {
16 private static void Main(string[] args)
17 {
18 BosClient client = GenerateBosClient();
19 const string bucketName = <SrcBucketName>;
20
21 // 初始化,创建示例Bucket和Object
22 client.CreateBucket(bucketName);
23 string objectName = <SrcObjectKey>;
24 client.PutObject(bucketName, objectName, <SrcSampleData>);
25
26 // 普通拷贝并打印结果
27 string newObjectName = <DesObjectKey>;
28 CopyObjectResponse copyObjectResponse = client.CopyObject(bucketName, objectName, bucketName,
29 newObjectName);
30
31 Console.WriteLine(Encoding.Default.GetString(client.GetObjectContent(bucketName, newObjectName)));
32
33 // 拷贝并设置新的meta
34 newObjectName = <DesObjectKey>;
35 CopyObjectRequest copyObjectRequest = new CopyObjectRequest()
36 {
37 SourceBucketName = bucketName,
38 SourceKey = objectName,
39 BucketName = bucketName,
40 Key = newObjectName
41 };
42 Dictionary<String, String> userMetadata = new Dictionary<String, String>();
43 userMetadata["usermetakey"] = "usermetavalue";
44 ObjectMetadata objectMetadata = new ObjectMetadata()
45 {
46 UserMetadata = userMetadata
47 };
48 copyObjectRequest.NewObjectMetadata = objectMetadata;
49 client.CopyObject(copyObjectRequest);
50 // usermetavalue
51 Console.WriteLine(client.GetObjectMetadata(bucketName, newObjectName).UserMetadata["usermetakey"]);
52 }
53
54 private static BosClient GenerateBosClient()
55 {
56 const string accessKeyId = <AccessKeyID>; // 您的Access Key ID
57 const string secretAccessKey = <SecretAccessKey>; // 您的Secret Access Key
58 const string endpoint = "https://bj.bcebos.com"; // 指定BOS服务域名
59
60 // 初始化一个BosClient
61 BceClientConfiguration config = new BceClientConfiguration();
62 config.Credentials = new DefaultBceCredentials(accessKeyId, secretAccessKey);
63 config.Endpoint = endpoint;
64
65 return new BosClient(config);
66 }
67 }
68}
Object的分块上传
除了通过putObject()方法上传文件到BOS以外,BOS还提供了另外一种上传模式:分块上传(Multipart Upload)。用户可以在如下的应用场景内(但不仅限于此),使用分块上传模式,如:
- 需要支持断点上传。
- 上传超过5GB大小的文件。
- 网络条件较差,和BOS的服务器之间的连接经常断开。
- 需要流式地上传文件。
- 上传文件之前,无法确定上传文件的大小。
分块完成Multipart Upload
假设有一个文件,本地路径为 d:\\sample.txt
,由于文件比较大,将其分块传输到BOS中。
-
基本流程
- 创建一个BosClient类的实例。
- 调用BosClient.InitiateMultipartUpload()方法。在调用该方法时您需要提供Bucket名称和Object名称,该方法会返回一个UploadId,在后面的步骤中需要用到该Id。
- 多次调用调用BosClient.UploadPart方法将文件分块多次上传。调用该方法时您需要提供Bucket名称,Object名称,UploadId,分块序号,分块大小,分块内容等参数,每次调用该方法都会返回本次分块的序号和ETag,在后面的步骤中会用到。
- 调用BosClient.CompleteMultipartUpload()方法完成本次分块上传。调用该方法您需要提供Bucket名称,Object名称,UploadId以及每个分块的序号和ETag。
- 上传过程中可以通过BosClient.ListParts()方法获取指定UploadId中已经上传的所有块;还可以通过BosClient.ListMultipartUploads()方法获取指定Bucket中所有未完成的UploadId。
初始化Multipart Upload
使用 InitiateMultipartUpload
方法来初始化一个分块上传事件:
-
示例代码
C#1// 开始Multipart Upload 2InitiateMultipartUploadRequest initiateMultipartUploadRequest = 3 new InitiateMultipartUploadRequest() {BucketName = bucketName, Key = objectKey}; 4InitiateMultipartUploadResponse initiateMultipartUploadResponse = 5 client.InitiateMultipartUpload(initiateMultipartUploadRequest); 6 7// 打印UploadId 8Console.WriteLine("UploadId: " + initiateMultipartUploadResponse.UploadId);
说明:
initiateMultipartUpload
的返回结果中含有UploadId
,它是区分分块上传事件的唯一标识,在后面的操作中,我们将用到它。
上传分块
把文件分块上传。
-
示例代码
C#1// 设置每块为 5Mb 2long partSize = 1024 * 1024 * 5L; 3 4FileInfo partFile = new FileInfo("my file"); 5 6// 计算分块数目 7int partCount = (int) (partFile.Length / partSize); 8if (partFile.Length % partSize != 0) 9{ 10 partCount++; 11} 12 13// 新建一个List保存每个分块上传后的ETag和PartNumber 14List<PartETag> partETags = new List<PartETag>(); 15 16for (int i = 0; i < partCount; i++) 17{ 18 // 获取文件流 19 Stream stream = partFile.OpenRead(); 20 21 // 跳到每个分块的开头 22 long skipBytes = partSize * i; 23 stream.Seek(skipBytes, SeekOrigin.Begin); 24 25 // 计算每个分块的大小 26 long size = Math.Min(partSize, partFile.Length - skipBytes); 27 28 // 创建UploadPartRequest,上传分块 29 uploadPartRequest uploadPartRequest = new UploadPartRequest(); 30 uploadPartRequest.BucketName = bucketName; 31 uploadPartRequest.Key = objectKey; 32 uploadPartRequest.UploadId = initiateMultipartUploadResponse.UploadId; 33 uploadPartRequest.InputStream = stream; 34 uploadPartRequest.PartSize = size; 35 uploadPartRequest.PartNumber = i + 1; 36 UploadPartResponse uploadPartResponse = client.UploadPart(uploadPartRequest); 37 38 // 将返回的PartETag保存到List中。 39 partETags.Add(new PartETag() 40 { 41 ETag = uploadPartResponse.ETag, 42 PartNumber = uploadPartResponse.PartNumber 43 }); 44 45 // 关闭文件 46 stream.Close(); 47 }
注意:
上面代码的核心是调用
UploadPart
方法来上传每一个分块,但是要注意以下几点:- 分块上传方法要求除最后一个Part以外,其他的Part大小都要大于等于5MB。但是Upload Part接口并不会检查上传Part的大小;只有当Complete Multipart Upload的时候才会校验。
- 为了保证数据在网络传输过程中不出现错误,建议您在
UploadPart
后,使用每个分块BOS返回的Content-MD5值分别验证已上传分块数据的正确性。当所有分块数据合成一个Object后,不再含MD5值。 - Part号码的范围是1~10000。如果超出这个范围,BOS将返回InvalidArgument的错误码。
- 每次上传Part时都要把流定位到此次上传块开头所对应的位置。
- 每次上传Part之后,BOS的返回结果会包含一个
PartETag
对象,它是上传块的ETag与块编号(PartNumber)的组合,在后续完成分块上传的步骤中会用到它,因此需要将其保存起来。一般来讲这些PartETag
对象将被保存到List中。
完成分块上传
-
示例代码
C#1CompleteMultipartUploadRequest completeMultipartUploadRequest = 2new CompleteMultipartUploadRequest() 3{ 4 BucketName = bucketName, 5 Key = objectKey, 6 UploadId = initiateMultipartUploadResponse.UploadId, 7 PartETags = partETags 8}; 9 10// 完成分块上传 11CompleteMultipartUploadResponse completeMultipartUploadResponse = 12client.CompleteMultipartUpload(completeMultipartUploadRequest); 13 14// 打印Object的ETag 15Console.WriteLine(completeMultipartUploadResponse.ETag);
说明:上面代码中的
partETags
是第二部中保存的partETag的列表,BOS收到用户提交的Part列表后,会逐一验证每个数据Part的有效性。当所有的数据Part验证通过后,BOS将把这些数据part组合成一个完整的Object。
取消分块上传事件
用户可以使用abortMultipartUpload方法取消分块上传。
-
示例代码
C#1AbortMultipartUploadRequest abortMultipartUploadRequest = new AbortMultipartUploadRequest() 2{ 3 BucketName = bucketName, 4 Key = objectKey, 5 UploadId = initiateMultipartUploadResponse.UploadId, 6}; 7 8// 取消分块上传 9client.AbortMultipartUpload(abortMultipartUploadRequest);
获取未完成的分块上传事件
用户可以使用 ListMultipartUploads
方法获取Bucket内未完成的分块上传事件。
-
示例代码
C#1ListMultipartUploadsRequest listMultipartUploadsRequest = 2 new ListMultipartUploadsRequest() {BucketName = bucketName}; 3 4// 获取Bucket内所有上传事件 5ListMultipartUploadsResponse listMultipartUploadsResponse = 6 client.ListMultipartUploads(listMultipartUploadsRequest); 7 8// 遍历所有上传事件 9foreach (MultipartUploadSummary multipartUpload in listMultipartUploadsResponse.Uploads) 10{ 11 Console.WriteLine("Key: " + multipartUpload.Key + " UploadId: " + multipartUpload.UploadId); 12}
注意:
- 默认情况下,如果Bucket中的分块上传事件的数目大于1000,则只会返回1000个,并且返回结果中IsTruncated的值为True,同时返回NextKeyMarker作为下次读取的起点。
- 若想获取更多分块上传事件,可以使用KeyMarker参数分次读取。
获取所有已上传的块信息
用户可以使用 ListParts
方法获取某个上传事件中所有已上传的块。
-
示例代码
C#1ListPartsRequest listPartsRequest = new ListPartsRequest() 2{ 3 BucketName = bucketName, 4 Key = objectKey, 5 UploadId = initiateMultipartUploadResponse.UploadId, 6}; 7 8// 获取上传的所有Part信息 9ListPartsResponse listPartsResponse = client.ListParts(listPartsRequest); 10 11// 遍历所有Part 12foreach (PartSummary part in listPartsResponse.Parts) 13{ 14 Console.WriteLine("PartNumber: " + part.PartNumber + " ETag: " + part.ETag); 15}
注意:
- 默认情况下,如果Bucket中的分块上传事件的数目大于1000,则只会返回1000个part,并且返回结果中IsTruncated的值为True,同时返回NextPartNumberMarker作为下次读取的起点。
- 若想获取更多已上传的分块信息,可以使用PartNumberMarker参数分次读取。
完整示例
下面示例代码演示了分块上传的完整过程:
1using System;
2using System.Collections.Generic;
3using System.IO;
4using System.Linq;
5using System.Text;
6using BaiduBce;
7using BaiduBce.Auth;
8using BaiduBce.Services.Bos;
9using BaiduBce.Services.Bos.Model;
10
11namespace DotnetSample
12{
13 internal class MultiUploadSample
14 {
15 private static void Main(string[] args)
16 {
17 BosClient client = GenerateBosClient();
18 const string bucketName = <BucketName>; //Bucket名称
19
20 // 初始化:创建示例Bucket
21 client.CreateBucket(bucketName);
22 string objectKey = <ObjectKey>;
23
24 // 开始Multipart Upload
25 InitiateMultipartUploadRequest initiateMultipartUploadRequest =
26 new InitiateMultipartUploadRequest() { BucketName = bucketName, Key = objectKey };
27 InitiateMultipartUploadResponse initiateMultipartUploadResponse =
28 client.InitiateMultipartUpload(initiateMultipartUploadRequest);
29
30 // 获取Bucket内的Multipart Upload
31 ListMultipartUploadsRequest listMultipartUploadsRequest =
32 new ListMultipartUploadsRequest() { BucketName = bucketName };
33 ListMultipartUploadsResponse listMultipartUploadsResponse =
34 client.ListMultipartUploads(listMultipartUploadsRequest);
35 foreach (MultipartUploadSummary multipartUpload in listMultipartUploadsResponse.Uploads)
36 {
37 Console.WriteLine("Key: " + multipartUpload.Key + " UploadId: " + multipartUpload.UploadId);
38 }
39
40 // 分块上传,首先设置每块为 5Mb
41 long partSize = 1024 * 1024 * 5L;
42 FileInfo partFile = new FileInfo("d:\\lzb\\sample");
43
44 // 计算分块数目
45 int partCount = (int)(partFile.Length / partSize);
46 if (partFile.Length % partSize != 0)
47 {
48 partCount++;
49 }
50
51 // 新建一个List保存每个分块上传后的ETag和PartNumber
52 List<PartETag> partETags = new List<PartETag>();
53 for (int i = 0; i < partCount; i++)
54 {
55 // 获取文件流
56 Stream stream = partFile.OpenRead();
57
58 // 跳到每个分块的开头
59 long skipBytes = partSize * i;
60 stream.Seek(skipBytes, SeekOrigin.Begin);
61
62 // 计算每个分块的大小
63 long size = Math.Min(partSize, partFile.Length - skipBytes);
64
65 // 创建UploadPartRequest,上传分块
66 UploadPartRequest uploadPartRequest = new UploadPartRequest();
67 uploadPartRequest.BucketName = bucketName;
68 uploadPartRequest.Key = objectKey;
69 uploadPartRequest.UploadId = initiateMultipartUploadResponse.UploadId;
70 uploadPartRequest.InputStream = stream;
71 uploadPartRequest.PartSize = size;
72 uploadPartRequest.PartNumber = i + 1;
73 UploadPartResponse uploadPartResponse = client.UploadPart(uploadPartRequest);
74
75 // 将返回的PartETag保存到List中。
76 partETags.Add(new PartETag()
77 {
78 ETag = uploadPartResponse.ETag,
79 PartNumber = uploadPartResponse.PartNumber
80 });
81
82 // 关闭文件
83 stream.Close();
84 }
85
86 // 获取UploadId的所有Upload Part
87 ListPartsRequest listPartsRequest = new ListPartsRequest()
88 {
89 BucketName = bucketName,
90 Key = objectKey,
91 UploadId = initiateMultipartUploadResponse.UploadId,
92 };
93
94 // 获取上传的所有Part信息
95 ListPartsResponse listPartsResponse = client.ListParts(listPartsRequest);
96
97 // 遍历所有Part
98 foreach (PartSummary part in listPartsResponse.Parts)
99 {
100 Console.WriteLine("PartNumber: " + part.PartNumber + " ETag: " + part.ETag);
101 }
102
103 // 完成分块上传
104 CompleteMultipartUploadRequest completeMultipartUploadRequest =
105 new CompleteMultipartUploadRequest()
106 {
107 BucketName = bucketName,
108 Key = objectKey,
109 UploadId = initiateMultipartUploadResponse.UploadId,
110 PartETags = partETags
111 };
112 CompleteMultipartUploadResponse completeMultipartUploadResponse =
113 client.CompleteMultipartUpload(completeMultipartUploadRequest);
114 Console.WriteLine(completeMultipartUploadResponse.ETag);
115 Console.ReadKey();
116 }
117
118 private static BosClient GenerateBosClient()
119 {
120 const string accessKeyId = <AccessKeyID>; // 您的Access Key ID
121 const string secretAccessKey = <SecretAccessKey>; // 您的Secret Access Key
122 const string endpoint = "https://bj.bcebos.com"; // 指定BOS服务域名
123
124 // 初始化一个BosClient
125 BceClientConfiguration config = new BceClientConfiguration();
126 config.Credentials = new DefaultBceCredentials(accessKeyId, secretAccessKey);
127 config.Endpoint = endpoint;
128
129 return new BosClient(config);
130 }
131 }
132}
支持单链接限速
对象存储BOS对单Bucket的公网带宽阈值为10Gbit/s,内网带宽阈值为50Gbit/s,当用户的上传或下载占用带宽达到带宽限制阈值时,会返回RequestRateLimitExceeded的错误码。为保证用户能够正常使用服务,BOS支持在进行上传、下载等行为时进行流量控制,保证大流量服务占用带宽不会对其他应用服务造成影响。
单链接限速上传和下载接口示例
限速值的取值范围为819200~838860800,单位为bit/s,即100KB/s~100MB/s。限速值取值必须为数字,BOS将按照指定的限速值对此次请求进行限速,当限速值不在此范围或不合法时将返回400错误码。
1public void ObjectTrafficLimit(BosClient client, String bucketName, String objectKey, byte[] byte1, String string1)
2{
3 // 具体的限速值
4 long trafficLimit = 819200;
5
6 // 获取指定文件
7 FileInfo file = new FileInfo(<FilePath>); //指定文件路径
8
9 // 生成put请求
10 PutObjectRequest putRequest = new PutObjectRequest()
11 {
12 BucketName = bucketName,
13 Key = objectKey,
14 FileInfo = file,
15 TrafficLimit = trafficLimit
16 };
17
18 // 以文件形式上传Object
19 PutObjectResponse putObjectFromFileResponse = client.PutObject(putRequest);
20
21 // 打印ETag
22 Console.WriteLine(putObjectFromFileResponse.ETAG);
23
24 // 生成get请求
25 GetObjectRequest getRequest = new GetObjectRequest()
26 {
27 BucketName = bucketName,
28 Key = objectKey,
29 TrafficLimit = trafficLimit
30 };
31
32 // 获取object
33 BosObject bosObject = client.GetObject(getRequest);
34
35 // 打印ETag
36 Console.WriteLine(bosObject.ObjectMetadata.ETag);
37}