# 快速入门(HarmonyOS SDK)
OBS SDK对**OBS** 服务提供的REST API进行封装，以简化用户的开发工作。您直接调用OBS SDK提供的接口函数即可使用**OBS**管理数据。
本章节介绍了OBS HarmonyOS SDK的快速入门，帮助您快速上手OBS的基础功能，包括创建桶、上传对象、下载对象、列举对象。
#### 准备工作
使用HarmonyOS SDK之前，您需要注册账号并实名认证、为账号充值，接着获取访问密钥、准备开发环境，然后下载并安装HarmonyOS SDK。
1. [注册账号](https://support.huaweicloud.com/usermanual-account/account_id_001.html)。
2. 为账号充值。 
   您需要确保账号有足够的余额，才能正常使用OBS等相关资源。请参考[账户充值](https://support.huaweicloud.com/usermanual-billing/bills-topic_30000002.html)。
   
   
3. 获取访问密钥，详情请参见[获取访问密钥（AK和SK）](https://support.huaweicloud.com/usermanual-ca/ca_01_0003.html)。
4. 准备开发环境，详情请参见[准备开发环境](https://support.huaweicloud.com/sdk-java-devg-obs/obs_21_0102.html#section2)。
5. 下载与安装HarmonyOS SDK，详情请参见[下载与安装SDK(HarmonyOS SDK)](https://support.huaweicloud.com/sdk-harmony-devg-obs/obs_34_0649.html)。
 
#### 步骤一：创建桶
本示例用于创建名为examplebucket的桶，并设置所在区域在华北-北京四（cn-north-4），桶ACL是私有，存储类型是低频访问存储，多AZ方式存储。
```
// 引入依赖包
import ObsClient, { AclType, StorageClassType, CreateBucketInput } from '@obs/esdk-obs-harmony';
import { process } from '@kit.ArkTS';
import { BusinessError } from '@kit.BasicServicesKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
const processManager = new process.ProcessManager();
// 创建ObsClient实例
const obsClient = new ObsClient({
  // 推荐通过环境变量获取AKSK，这里也可以使用其他外部引入方式传入，如果使用硬编码可能会存在泄露风险
  // 您可以登录访问管理控制台获取访问密钥AK/SK，获取方式请参见https://support.huaweicloud.com/usermanual-ca/ca_01_0003.html
  AccessKeyId: processManager.getEnvironmentVar("ACCESS_KEY_ID"),
  SecretAccessKey: processManager.getEnvironmentVar("SECRET_ACCESS_KEY"),
  // 【可选】如果使用临时AK/SK和SecurityToken访问OBS，同样建议您尽量避免使用硬编码，以降低信息泄露风险。您可以通过环境变量获取访问密钥AK/SK，也可以使用其他外部引入方式传入
  // SecurityToken: processManager.getEnvironmentVar("SECURITY_TOKEN"),
  // Server填写Bucket对应的Endpoint, 这里以华北-北京四为例，其他地区请按实际情况填写
  Server: "https://obs.cn-north-4.myhuaweicloud.com",
});
async function createBucket() {
  try {
    const params: CreateBucketInput = {
      // 指定存储桶名称
      Bucket: "examplebucket",
      // 指定存储桶所在区域，此处以“cn-north-4”为例，必须跟传入的Endpoint中Region保持一致
      Location: "cn-north-4",
      // 指定存储桶ACL，此处以AclType.PRIVATE为例
      Acl: AclType.PRIVATE,
      // 指定存储桶的存储类型，此处以StorageClassType.WARM为例。如果未指定该参数，则创建的桶为标准存储
      StorageClass: StorageClassType.WARM,
      // 指定存储桶的AZ类型，此处以“3az”为例。不携带时默认为单AZ，如果对应region不支持多AZ存储，则该桶的存储类型仍为单AZ
      AzRedundancy: "3az",
    };
    // 创建桶
    const result = await obsClient.createBucket(params);
    if (result.CommonMsg.Status < 300) {
      hilog.info(0x0001, 'OBS-Harmony', "Create bucket(%s) successful!", params.Bucket);
      hilog.info(0x0001, 'OBS-Harmony', "RequestId: %s", result.CommonMsg.RequestId);
      return;
    }
    hilog.error(0x0001, 'OBS-Harmony', "An ObsError was found, which means your request sent to OBS was rejected with an error response.");
    hilog.error(0x0001, 'OBS-Harmony', "Status: %d", result.CommonMsg.Status);
    hilog.error(0x0001, 'OBS-Harmony', "Code: %s", result.CommonMsg.Code);
    hilog.error(0x0001, 'OBS-Harmony', "Message: %s", result.CommonMsg.Message);
    hilog.error(0x0001, 'OBS-Harmony', "RequestId: %s", result.CommonMsg.RequestId);
  } catch (error) {
    const err = error as BusinessError;
    hilog.error(0x0001, 'OBS-Harmony', 'An Exception occurred: code=%d, message: %s', err.code, err.message);
  }
}
createBucket();
```
#### 步骤二：上传对象
二进制文件上传，上传后的对象命名为example/objectname，对象存储在名为examplebucket的桶中。
```
// 引入依赖包
import ObsClient, { PutObjectInput } from '@obs/esdk-obs-harmony';
import { fileIo as fs } from '@kit.CoreFileKit';
import { process } from '@kit.ArkTS';
import { BusinessError } from '@kit.BasicServicesKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
const processManager = new process.ProcessManager();
// 创建ObsClient实例
const obsClient = new ObsClient({
  // 推荐通过环境变量获取AKSK，这里也可以使用其他外部引入方式传入，如果使用硬编码可能会存在泄露风险
  // 您可以登录访问管理控制台获取访问密钥AK/SK，获取方式请参见https://support.huaweicloud.com/usermanual-ca/ca_01_0003.html
  AccessKeyId: processManager.getEnvironmentVar("ACCESS_KEY_ID"),
  SecretAccessKey: processManager.getEnvironmentVar("SECRET_ACCESS_KEY"),
  // 【可选】如果使用临时AK/SK和SecurityToken访问OBS，同样建议您尽量避免使用硬编码，以降低信息泄露风险。您可以通过环境变量获取访问密钥AK/SK，也可以使用其他外部引入方式传入
  // SecurityToken: processManager.getEnvironmentVar("SECURITY_TOKEN"),
  // Server填写Bucket对应的Endpoint, 这里以华北-北京四为例，其他地区请按实际情况填写
  Server: "https://obs.cn-north-4.myhuaweicloud.com",
});
async function putObject() {
  // 指定文件路径，这里以cacheDir目录下的hello.txt为例，需要保证fs模块可以正常读取。
  let sourceFile = getContext().cacheDir + "/hello.txt";
  // 打开文件句柄，如果代码运行在生产环境上，推荐加上异常捕获（try...catch）逻辑。
  let file = fs.openSync(sourceFile, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE | fs.OpenMode.TRUNC);
  // 模拟文件内容
  fs.writeSync(file.fd, "Hello OBS");
  // 获取文件属性
  let fileStat = fs.statSync(file.fd);
  // 根据文件大小 构建文件缓冲区
  let buf = new ArrayBuffer(fileStat.size);
  fs.readSync(file.fd, buf, { offset: 0 });
  // 用完记得关闭文件
  fs.closeSync(file.fd);
  try {
    const params: PutObjectInput = {
      // 指定存储桶名称
      Bucket: "examplebucket",
      // 指定对象，此处以 example/objectname 为例
      Key: "example/objectname",
      // 指定上传内容，注意这里接收的类型是ArrayBuffer
      Body: buf
    };
    // 上传对象
    const result = await obsClient.putObject(params);
    if (result.CommonMsg.Status < 300) {
      hilog.info(0x0001, 'OBS-Harmony', "Put object(%s) under the bucket(%s) successful!!", params.Key, params.Bucket);
      hilog.info(0x0001, 'OBS-Harmony', "RequestId: %s", result.CommonMsg.RequestId);
      hilog.info(0x0001, 'OBS-Harmony', "StorageClass:%s, ETag:%s", result.InterfaceResult.StorageClass, result.InterfaceResult.ETag);
      return;
    }
    hilog.error(0x0001, 'OBS-Harmony', "An ObsError was found, which means your request sent to OBS was rejected with an error response.");
    hilog.error(0x0001, 'OBS-Harmony', "Status: %d", result.CommonMsg.Status);
    hilog.error(0x0001, 'OBS-Harmony', "Code: %s", result.CommonMsg.Code);
    hilog.error(0x0001, 'OBS-Harmony', "Message: %s", result.CommonMsg.Message);
    hilog.error(0x0001, 'OBS-Harmony', "RequestId: %s", result.CommonMsg.RequestId);
    return;
  } catch (error) {
      const err = error as BusinessError;
      hilog.error(0x0001, 'OBS-Harmony', 'An Exception occurred: code=%d, message: %s', err.code, err.message);
  }
}
putObject();
```
#### 步骤三：下载对象
本示例用于文本下载examplebucket桶中的example/objectname对象。
```
// 引入依赖包
import ObsClient, { GetObjectInput } from '@obs/esdk-obs-harmony';
import { process } from '@kit.ArkTS';
import { BusinessError } from '@kit.BasicServicesKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
const processManager = new process.ProcessManager();
// 创建ObsClient实例
const obsClient = new ObsClient({
  // 推荐通过环境变量获取AKSK，这里也可以使用其他外部引入方式传入，如果使用硬编码可能会存在泄露风险
  // 您可以登录访问管理控制台获取访问密钥AK/SK，获取方式请参见https://support.huaweicloud.com/usermanual-ca/ca_01_0003.html
  AccessKeyId: processManager.getEnvironmentVar("ACCESS_KEY_ID"),
  SecretAccessKey: processManager.getEnvironmentVar("SECRET_ACCESS_KEY"),
  // 【可选】如果使用临时AK/SK和SecurityToken访问OBS，同样建议您尽量避免使用硬编码，以降低信息泄露风险。您可以通过环境变量获取访问密钥AK/SK，也可以使用其他外部引入方式传入。
  // SecurityToken: processManager.getEnvironmentVar("SECURITY_TOKEN"),
  // Server填写Bucket对应的Endpoint, 这里以华北-北京四为例，其他地区请按实际情况填写。
  Server: "https://obs.cn-north-4.myhuaweicloud.com",
});
async function getObject() {
  try {
    const params: GetObjectInput = {
      // 指定存储桶名称
      Bucket: "examplebucket",
      // 指定下载对象，此处以 example/objectname 为例。
      Key: 'example/objectname',
    };
    
    // 文本下载对象
    const result = await obsClient.getObject(params);
    if (result.CommonMsg.Status < 300) {
      hilog.info(0x0001, 'OBS-Harmony', "Get object(%s) under the bucket(%s) successful!", params.Key, params.Bucket);
      hilog.info(0x0001, 'OBS-Harmony', "RequestId: %s", result.CommonMsg.RequestId);
      hilog.info(0x0001, 'OBS-Harmony', 'Object Content: %s', result.InterfaceResult.Content); 
      return;
    }
    hilog.error(0x0001, 'OBS-Harmony', "An ObsError was found, which means your request sent to OBS was rejected with an error response.")
    hilog.error(0x0001, 'OBS-Harmony', "Status: %d", result.CommonMsg.Status);
    hilog.error(0x0001, 'OBS-Harmony', "Code: %s", result.CommonMsg.Code);
    hilog.error(0x0001, 'OBS-Harmony', "Message: %s", result.CommonMsg.Message);
    hilog.error(0x0001, 'OBS-Harmony', "RequestId: %s", result.CommonMsg.RequestId);
  } catch (error) {
    const err = error as BusinessError;
    hilog.error(0x0001, 'OBS-Harmony', 'An Exception occurred: code=%d, message: %s', err.code, err.message);
  }
}
getObject();
```
#### 步骤四：简单列举对象
本示例用于获取名为examplebucket桶下的对象列表，其中列举的是以test/ 开头的所有对象中的按照字典顺序的最多前100个对象，并且是从起始位置test/test2开始列举。
```
// 引入依赖包
import ObsClient, { ListObjectsInput } from '@obs/esdk-obs-harmony';
import { process } from '@kit.ArkTS';
import { BusinessError } from '@kit.BasicServicesKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
const processManager = new process.ProcessManager();
// 创建ObsClient实例
const obsClient = new ObsClient({
  // 推荐通过环境变量获取AKSK，这里也可以使用其他外部引入方式传入，如果使用硬编码可能会存在泄露风险
  // 您可以登录访问管理控制台获取访问密钥AK/SK，获取方式请参见https://support.huaweicloud.com/usermanual-ca/ca_01_0003.html
  AccessKeyId: processManager.getEnvironmentVar("ACCESS_KEY_ID"),
  SecretAccessKey: processManager.getEnvironmentVar("SECRET_ACCESS_KEY"),
  // 【可选】如果使用临时AK/SK和SecurityToken访问OBS，同样建议您尽量避免使用硬编码，以降低信息泄露风险。您可以通过环境变量获取访问密钥AK/SK，也可以使用其他外部引入方式传入
  // SecurityToken: processManager.getEnvironmentVar("SECURITY_TOKEN"),
  // Server填写Bucket对应的Endpoint, 这里以华北-北京四为例，其他地区请按实际情况填写
  Server: "https://obs.cn-north-4.myhuaweicloud.com",
});
async function listObjects() {
  try {
    const params: ListObjectsInput = {
      // 指定存储桶名称
      Bucket: "examplebucket",
      // 指定列举对象前缀，此处以“test/”前缀为例，满足指定前缀的对象会被列举
      Prefix: "test/",
      // 指定返回的最大对象数，此处以 100 为例，返回的对象列表将是按照字典顺序的最多前max-keys个对象，默认值为1000
      MaxKeys: 100,
      // 指定对象名分组的分隔符，这里以/为例。
      Delimiter: "/",
      // 指定列举对象的起始位置，此处以“test/test2”为例
      Marker: "test/test2",
      // 指定编码方式，此处以“url”为例，如果列举对象中存在特殊字符，则该参数必传
      EncodingType: "url"
    };
    // 列举桶内对象
    const result = await obsClient.listObjects(params);
    if (result.CommonMsg.Status < 300) {
      hilog.info(0x0001, 'OBS-Harmony', "List objects under the bucket(%s) successful!", params.Bucket);
      hilog.info(0x0001, 'OBS-Harmony', "RequestId: %s", result.CommonMsg.RequestId);
      for (let j = 0; j < result.InterfaceResult.Contents.length; j++) {
        const val = result.InterfaceResult.Contents[j];
        hilog.info(0x0001, 'OBS-Harmony', 'Content[%d]-OwnerId:%s, ETag:%s, Key:%s, LastModified:%s, Size:%d',
          j, val.Owner.ID, val.ETag, val.Key, val.LastModified, val.Size);
      }
      return;
    }
    hilog.error(0x0001, 'OBS-Harmony', "An ObsError was found, which means your request sent to OBS was rejected with an error response.");
    hilog.error(0x0001, 'OBS-Harmony', "Status: %d", result.CommonMsg.Status);
    hilog.error(0x0001, 'OBS-Harmony', "Code: %s", result.CommonMsg.Code);
    hilog.error(0x0001, 'OBS-Harmony', "Message: %s", result.CommonMsg.Message);
    hilog.error(0x0001, 'OBS-Harmony', "RequestId: %s", result.CommonMsg.RequestId);
  } catch (error) {
    const err = error as BusinessError;
    hilog.error(0x0001, 'OBS-Harmony', 'An Exception occurred: code=%d, message: %s', err.code, err.message);
  }
}
listObjects();
```
#### 相关信息
当您完成创建桶、上传对象、下载对象等基本操作后，您还可以结合业务需求使用以下HarmonyOS SDK的高阶功能。
- [生命周期](https://support.huaweicloud.com/sdk-harmony-devg-obs/obs_34_0321.html)：通过为桶配置生命周期规则，可以实现定时转换对象存储类别或定时删除对象。
- [桶ACL权限](https://support.huaweicloud.com/sdk-harmony-devg-obs/obs_34_0314.html)：HarmonyOS SDK提供桶ACL访问权限方式，桶的所有者可以通过编写桶ACL，实现对桶更精细化的权限控制。
- [桶策略](https://support.huaweicloud.com/sdk-harmony-devg-obs/obs_34_0318.html)：HarmonyOS SDK提供桶策略访问权限方式，桶的所有者可以通过编写桶策略，实现对桶更精细化的权限控制。
- [静态网站托管](https://support.huaweicloud.com/sdk-harmony-devg-obs/obs_34_0324.html)：您可以将静态网站文件上传至OBS的桶中，并对这些文件赋予匿名用户可读权限，然后将该桶配置成静态网站托管模式，实现使用桶域名访问该网站。
- [多版本控制](https://support.huaweicloud.com/sdk-harmony-devg-obs/obs_34_0327.html)：为桶开启多版本控制后，可以在桶中保留多个版本的对象，方便检索和还原各个版本，在意外操作或应用程序故障时帮助快速恢复数据。
- [跨域资源共享（CORS）](https://support.huaweicloud.com/sdk-harmony-devg-obs/obs_34_0640.html)：通过配置CORS规则，可以实现跨域名访问OBS。
 
