对象存储BOS

    Object管理

    上传Object

    最简单的上传

    • 基本流程

      1. 创建一个BOSClient类的实例。
      2. 调用BOSClient.PutObject()方法。调用该方法时您需要提供Bucket名称、ObjectKey和Object的内容。可以通过如下四种方式上传Object:文件、数据流、二进制串和字符串的形式。
    • 示例代码
    public void PutObject(BosClient client, String bucketName, String objectKey, byte[] byte1, String string1)
    {
    
        // 获取指定文件
        FileInfo file = new FileInfo(<FilePath>);    //指定文件路径
    
        // 以文件形式上传Object
        PutObjectResponse putObjectFromFileResponse = client.PutObject(bucketName, objectKey, file);
    
        // 获取数据流
        Stream inputStream = file.OpenRead();
    
        // 以数据流形式上传Object
        PutObjectResponse putObjectResponseFromInputStream = client.PutObject(bucketName, objectKey, inputStream);
    
        // 以二进制串上传Object
        PutObjectResponse putObjectResponseFromByte = client.PutObject(bucketName, objectKey,Encoding.Default.GetBytes("sampledata"));
    
        // 以字符串上传Object
        PutObjectResponse putObjectResponseFromString = client.PutObject(bucketName, objectKey, "sampledata");
    
        // 打印ETag
        Console.WriteLine(putObjectFromFileResponse.ETAG);
    
    }

    说明:Object以文件的形式上传到BOS中,putObject函数支持不超过5GB的Object上传。在putObject请求处理成功后,BOS会在Header中返回Object的ETag作为文件标识。

    设定Object的Http Header

    BOS支持您在上传object时设定Http Header。

    • 基本流程

      1. 创建一个BOSClient类的实例。
      2. 调用BOSClient.PutObject()时候,您还可以传入一个ObjectMetadata对象,该对象可以设置自定义的Http Header。
    • 示例代码
    // 初始化上传输入流
    ObjectMetadata meta = new ObjectMetadata();
    
    // 设置ContentLength大小
    meta.ContentLength = <Length>;
    
    // 设置ContentType
    meta.ContentType = "application/json";
    
    client.PutObject(bucketName, objectKey, <SampleData>, meta);

    用户自定义元数据

    • 基本流程

      1. 创建一个BOSClient类的实例。
      2. 调用BOSClient.PutObject()时候,您还可以传入一个ObjectMetadata对象,该对象支持用户自定义元数据来对Object进行描述。
    • 示例代码
    // 设置自定义元数据name的值为my-data
    meta.UserMetadata["name"] = "my-data";
    
    // 上传Object
    client.PutObject(bucketName, objectKey, <SampleData>, meta);
    > **说明:**在上面代码中,用户自定义了一个名字为”name”,值为”my-data”的元数据。当用户下载此Object的时候,此元数据也可以一并得到。一个Object可以有多个类似的参数,但所有的User Meta总大小不能超过2KB。

    完整示例

    下面示例代码演示了简单上传Object、设定Object的Http Header和用户自定义元数据的完整过程:

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Text;
    using BaiduBce;
    using BaiduBce.Auth;
    using BaiduBce.Services.Bos;
    using BaiduBce.Services.Bos.Model;
    
    namespace DotnetSample
    {
        internal class PutObjectSample
        {
            private static void Main(string[] args)
            {
                BosClient client = GenerateBosClient();
                const string bucketName = <BucketName>;        //您的Bucket名称
                const string objectNameFile = <ObjectNameFile>;  //文件形式上传的Object名称
                const string objectNameStream = <ObjectNameStream>; //数据流形式上传的Object名称
                const string objectNameString = <ObjectNameString>; //字符串形式上传的Object名称
                const string objectNameByte = <ObjectNameByte>; //二进制形式上传的Object名称
    
                // 新建一个Bucket
                client.CreateBucket(bucketName); //指定Bucket名称
    
                // 设置待上传的文件名
                const string fileName = "d:\\sample.txt";
    
                // 以文件形式上传Object
                PutObjectResponse putObjectFromFileResponse = client.PutObject(bucketName, objectNameFile,
                    new FileInfo(fileName));
    
                // 以数据流形式上传Object
                PutObjectResponse putObjectResponseFromInputStream = client.PutObject(bucketName, objectNameStream,
                    new FileInfo(fileName).OpenRead());
    
                // 以二进制串上传Object
                PutObjectResponse putObjectResponseFromByte = client.PutObject(bucketName, objectNameByte,
                    Encoding.Default.GetBytes("sampledata"));
    
                // 以字符串上传Object
                PutObjectResponse putObjectResponseFromString = client.PutObject(bucketName, objectNameString,
                    "sampledata");
    
                // 打印四种方式的ETag。示例中,文件方式和stream方式的ETag相等,string方式和byte方式的ETag相等
                Console.WriteLine(putObjectFromFileResponse.ETAG);
                Console.WriteLine(putObjectResponseFromInputStream.ETAG);
                Console.WriteLine(putObjectResponseFromByte.ETAG);
                Console.WriteLine(putObjectResponseFromString.ETAG);
    
                // 上传Object并设置自定义参数
                ObjectMetadata meta = new ObjectMetadata();
                // 设置ContentLength大小
                meta.ContentLength = 10;
                // 设置ContentType
                meta.ContentType = "application/json";
                // 设置自定义元数据name的值为my-data
                meta.UserMetadata["name"] = "my-data";
                // 上传Object并打印ETag
                putObjectResponseFromString = client.PutObject(bucketName, objectNameString, "sampledata", meta);
                Console.WriteLine(putObjectResponseFromString.ETAG);
            }
    
            private static BosClient GenerateBosClient()
            {
                const string accessKeyId = <AccessKeyID>; // 您的Access Key ID
                const string secretAccessKey = <SecretAccessKey>; // 您的Secret Access Key
                const string endpoint = <EndPoint>; // 指定BOS服务域名
    
                // 初始化一个BosClient
                BceClientConfiguration config = new BceClientConfiguration();
                config.Credentials = new DefaultBceCredentials(accessKeyId, secretAccessKey);
                config.Endpoint = endpoint;
    
                return new BosClient(config);
            }
        }
    }

    查看Bucket中的Object

    简单查询

    查看Bucket中Object列表。

    • 基本流程

      1. 创建一个BOSClient类的实例。
      2. 调用BOSClient.ListObjects()方法。调用该方法时你需要提供Bucket名称。
    • 示例代码

      public void ListObjects(BosClient client, string bucketName)
      {
      
          // 获取指定Bucket下的所有Object信息
          ListObjectsResponse listObjectsResponse = client.ListObjects(bucketName);
      
          // 遍历所有Object
          foreach (BosObjectSummary objectSummary in listObjectsResponse.Contents)
          {
              Console.WriteLine("ObjectKey: " + objectSummary.Key);
          }
      
      }

      说明: 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值之后按字母排序开始返回。
    -
    • 基本流程

      1. 创建一个BOSClient类的实例。
      2. 您也可以构造一个ListObjectsRequest来调用ListObjects(),ListObjectsRequest等方法,实现更多的扩展查询操作。
    • 示例代码

      // 构造ListObjectsRequest请求
      ListObjectsRequest listObjectsRequest = new ListObjectsRequest() {BucketName = bucketName};
      
      // 设置参数
      listObjectsRequest.Delimiter=<Delimiter>;
      listObjectsRequest.Marker=<Marker>;
      
      ListObjectsResponse listObjectsResponse = client.ListObjects(listObjectsRequest);

      说明:

      上面代码中调用了 listObjects 中的一个重载方法,通过传入 ListObjectsRequest 来完成请求。

    • 完整示例

      请参考完整示例

    查询模拟文件夹

    由于BOS本身是一个(<Key>,<Value>)的存储系统,所以原则上并不会存在“文件夹”的概念,但您可以通过 DelimiterPrefix 参数的配合进行文件夹功能模拟。

    假设Bucket中有5个文件:bos.jpg,fun/,fun/test.jpg,fun/movie/001.avi,fun/movie/007.avi,可以把 “/” 符号作为分隔符模拟文件夹。

    递归列出模拟文件夹下所有文件

    可以通过设置 Prefix 参数来获取某个目录下所有的文件:

    // 构造ListObjectsRequest请求
    ListObjectsRequest listObjectsRequest = new ListObjectsRequest() {BucketName = bucketName};
    
    // 递归列出fun目录下的所有文件
    listObjectsRequest.Prefix = "fun/";
    
    // List Objects
    ListObjectsResponse listObjectsResponse = client.ListObjects(listObjectsRequest);
    
    // 遍历所有Object
    Console.WriteLine("Objects:");
    foreach (BosObjectSummary objectSummary in listObjectsResponse.Contents)
    {
        Console.WriteLine("ObjectKey: " + objectSummary.Key);
    }

    输出:

    Objects:
    fun/
    fun/movie/001.avi
    fun/movie/007.avi
    fun/test.jpg

    查看模拟文件夹下的文件和子文件夹

    PrefixDelimiter 结合的情况下,可以列出模拟文件夹下的文件和子文件夹:

    // 构造ListObjectsRequest请求
    ListObjectsRequest listObjectsRequest = new ListObjectsRequest() {BucketName = bucketName};
    
    // "/" 为文件夹的分隔符
    listObjectsRequest.Delimiter = "/";
    
    // 列出fun目录下的所有文件和文件夹
    listObjectsRequest.Prefix = "fun/";
    
    // List Objects
    ListObjectsResponse listObjectsResponse = client.ListObjects(listObjectsRequest);
    
    // 遍历所有Object,相当于获取fun目录下的所有文件
    Console.WriteLine("Objects:");
    foreach (BosObjectSummary objectSummary in listObjectsResponse.Contents)
    {
        Console.WriteLine("ObjectKey: " + objectSummary.Key);
    }
    
    // 遍历所有CommonPrefix,相当于获取fun目录下的所有文件夹
    Console.WriteLine("\nCommonPrefixs:");
    foreach (ObjectPrefix objectPrefix in listObjectsResponse.CommonPrefixes)
    {
        Console.WriteLine(objectPrefix.Prefix);
    }

    输出:

    Objects:
    fun/
    fun/test.jpg
    
    CommonPrefixs:
    fun/movie/

    说明:

    返回的结果中, Objects 的列表中给出的是fun文件夹下的文件。而 CommonPrefixs 的列表中给出的是fun文件夹下的所有子文件夹。可以看出 fun/movie/001.avifun/movie/007.avi 两个文件并没有被列出来,因为它们属于 fun 文件夹下的 movie 子文件夹下的文件。

    完整示例

    下面示例代码演示了Object的简单查询、使用nextmarker分次查询、扩展查询、查询模拟文件夹的完整过程:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using BaiduBce;
    using BaiduBce.Auth;
    using BaiduBce.Services.Bos;
    using BaiduBce.Services.Bos.Model;
    
    namespace DotnetSample
    {
        internal class ListObjectsSample
        {
            private static void Main(string[