华为OBS对象存储

一.SDK概述

对象存储服务软件开发工具包(OBS SDK,Object Storage Service Software Development Kit)是对OBS服务提供的REST API进行的封装,以简化用户的开发工作。用户直接调用OBS SDK提供的接口函数即可实现使用OBS服务业务能力的目的。相关开发包请从华为云OBS开发工具包(SDK)(https://developer.huaweicloud.com/sdk?OBS)获取。

二.java SDK开发入门

2.1、安装SDK

打开maven工程的pom.xml,在节点中加入以下配置

<!--obs依赖 -->
<dependency>
    <groupId>com.huaweicloud</groupId>
    <artifactId>esdk-obs-java</artifactId>
    <version>3.0.3</version>
</dependency>

2.2、初始化OBS客户端

向OBS发送任意HTTP/HTTPS请求之前,必须先创建一个ObsClient实例:

String endPoint = "https://your-endpoint";
String ak = "*** Provide your Access Key ***";
String sk = "*** Provide your Secret Key ***";
// 创建ObsClient实例
ObsClient obsClient = new ObsClient(ak, sk, endPoint);
 
// 使用访问OBS
        
// 关闭obsClient
obsClient.close();

创建桶:桶是OBS全局命名空间,相当于数据的容器,文件系统的根目录,可以存储若干对象,以下代码展示如何创建一个桶:(如有桶可不创建)

obsClient.createBucket("bucketname");
  • 桶的名字是全局唯一的,所以您需要确保不与已有的桶名称重复。
  • 桶命名规则如下:
  • 3~63个字符,数字或字母开头,支持小写字母、数字、“-”、“.”。
  • 禁止使用类IP地址。
  • 禁止以“-”或“.”开头及结尾。
  • 禁止两个“.”相邻(如:“my…bucket”)。
  • 禁止“.”和“-”相邻(如:“my-.bucket”和“my.-bucket”)。
  • 同一用户多次创建同名桶不会报错,创建的桶属性以第一次请求为准。
  • 更多创建桶的信息,请参见创建桶

2.3、上传对象

obsClient.putObject("bucketname", "objectname", new ByteArrayInputStream("Hello OBS".getBytes()));

上传对象方式:

2.4、下载对象

以下代码展示如何获取对象的内容

ObsObject obsObject = obsClient.getObject("bucketname", "objectname");
InputStream content = obsObject.getObjectContent();
if (content != null)
{
    BufferedReader reader = new BufferedReader(new InputStreamReader(content));
    while (true)
    {
        String line = reader.readLine();
        if (line == null)
            break;
        System.out.println("\n" + line);
    }
    reader.close();
}
  • 调用ObsClient.getObject返回一个ObsObject实例,该实例包含对象内容及其属性。
  • 调用ObsObject.getObjectContent获取对象输入流,可读取此输入流获取其内容,用完之后请关闭这个流。
  • 更多下载对象的信息,请参见下载对象

2.5、列举对象

当完成一系列上传对象操作后,可能需要查看桶中包含哪些对象。以下代码展示如何列举指定桶中对的对象:

ObjectListing objectListing = obsClient.listObjects("bucketname");
for(ObsObject obsObject : objectListing.getObjects()){
    System.out.println(" - " + obsObject.getObjectKey() + "  " +  "(size = " + obsObject.getMetadata().getContentLength() + ")");
}
  • 调用ObsClient.listObjects返回ObjectListing实例,该实例包含此次listObject请求的返回结果,可通过ObjetListing.getObjects获取所有对象(Object)的描述信息。
  • 上面的代码默认列举1000个对象(Object)。
  • 更丰富的列举功能,请参见列举对象

2.6、删除对象

以下代码展示如何删除指定的对象

obsClient.deleteObject("bucketname", "objectname");

2.7、OBS客户端通用示例

使用OBS客户端进行接口调用操作完成后,没有异常抛出,则表明返回值有效,返回SDK公共响应头实例或其子类实例;若抛出异常,则说明操作失败,此时应从SDK自定义异常 实例中获取错误信息。

以下代码展示了使用OBS客户端的通用方式:

// 您的工程中可以只保留一个全局的ObsClient实例
// ObsClient是线程安全的,可在并发场景下使用
ObsClient obsClient = null; 
try
{
    String endPoint = "https://your-endpoint";
    String ak = "*** Provide your Access Key ***";
    String sk = "*** Provide your Secret Key ***";
    // 创建ObsClient实例
    obsClient = new ObsClient(ak, sk, endPoint);
    // 调用接口进行操作,例如上传对象
    HeaderResponse response = obsClient.putObject("bucketname", "objectname", new File("localfile"));  // localfile为待上传的本地文件路径,需要指定到具体的文件名
    System.out.println(response);
}
catch (ObsException e)
{
    System.out.println("HTTP Code: " + e.getResponseCode());
    System.out.println("Error Code:" + e.getErrorCode());
    System.out.println("Error Message: " + e.getErrorMessage());
    
    System.out.println("Request ID:" + e.getErrorRequestId());
    System.out.println("Host ID:" + e.getErrorHostId());
}finally{
    // 关闭ObsClient实例,如果是全局ObsClient实例,可以不在每个方法调用完成后关闭
    // ObsClient在调用ObsClient.close方法关闭后不能再次使用
    if(obsClient != null){
        try
        {
            // obsClient.close();
        }
        catch (IOException e)
        {
        }
    }
}

3、注意

如果同一个桶上传文件时,文件名重复,会覆盖之前上传的文件,可以重命名文件名,使用时间来区分文件:

private static int i = 0;
String filenameStr = file.getOriginalFilename();
String[] split = filenameStr.split("\\.");
String s = split[split.length-1];
SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");//设置日期格式
if (i>=10){
    i = 0;
}
String filename = "gl"+i+"D"+df.format(new Date())+"."+s;// new Date()为获取当前系统时间,也可使用当前时间戳
++i;
log.info("上传文件名为:{}",filename);