HarmonyOS —— Remote Communication Kit 文件上传 下载快速实现笔记

HarmonyOS —— Remote Communication Kit 文件上传 / 下载快速实现笔记

这篇就当是我啃完“快速实现上传下载”这一节之后给自己留的实战小抄:
用 Remote Communication Kit 负责“远程通信”,Core File Kit 负责“本地文件读写”,两者一结合,文件 / 目录 / 对象的上传下载就非常顺手。


一、整体思路:RCP + Core File Kit 怎么配合?

鸿蒙开发者第四期活动

  • Remote Communication Kit(RCP)
    负责「怎么跟远端服务打交道」,比如:
    • 建立 HTTP 会话
    • 传输数据(downloadToFile / uploadFromFile)
    • 配置超时、安全、TLS 等
  • Core File Kit(fileIo)
    负责「怎么和本地文件打交道」,比如:
    • 打开文件(openSync)
    • 读写文件(read / write)
    • 目录 / 文件是否存在、删除等(accessSync / rmdirSync / unlinkSync)

两者搭配使用,就可以做到:

  • 下载:RCP 从远端拉文件 → Core File Kit 帮我们落到本地路径 / 目录
  • 上传:Core File Kit 先从本地文件读内容 → RCP 再把内容上传到远端 URL

二、设备 & 版本支持(熟悉的配方)

和前面 Remote Communication Kit 的其他能力一样:

  • 支持设备:Phone / 2in1 / Tablet / Wearable
  • 5.1.1(19) 起:新增支持 TV

一句话记:

文件上传下载能力支持 Phone / 2in1 / Tablet / Wearable,5.1.1(19) 起支持 TV


三、下载实现:downloadToFile + Core File Kit

1. 引入模块

import { rcp } from '@kit.RemoteCommunicationKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { fileIo } from '@kit.CoreFileKit';
  • rcp:发起 HTTP 会话、下载
  • fileIo:操作本地文件 / 目录

2. 定义下载目录 & 安全配置

// 下载文件保存的文件夹路径,仅为示例,请按需求进行替换。
const DOWNLOAD_TO_PATH = `/data/storage/el2/base/haps/entry/files`;

// 安全配置:这里把 remoteValidation 设置成 'skip',表示跳过证书校验(⚠ 一般只建议用于测试环境)
const securityConfig: rcp.SecurityConfiguration = {
  remoteValidation: 'skip'
};

// 下载配置:表示“下载到一个文件夹”
let downloadToFile: rcp.DownloadToFile = {
  kind: 'folder',
  path: DOWNLOAD_TO_PATH
};

🔎 提醒:
remoteValidation: 'skip' 是“关闭证书校验”,生产环境不要这么搞,正式接入要么用 'system',要么配置自己的 CA / 证书校验逻辑。


3. 创建带超时 & 安全配置的 Session

const session = rcp.createSession({
  requestConfiguration: {
    transfer: {
      timeout: {
        connectMs: 6000,
        transferMs: 6000,
        inactivityMs: 6000
      }
    },
    security: securityConfig
  }
});
  • connectMs:连接超时时间
  • transferMs:传输整体超时时间
  • inactivityMs:传输过程“无数据活动”多久算超时
    → 这些可以根据你的业务规模自行调大/调小。

4. 检查目标路径 & 发起下载

// 检查目标路径是否存在,如果存在就先删除(避免旧文件/目录干扰)
if (fileIo.accessSync(DOWNLOAD_TO_PATH)) {
  fileIo.rmdirSync(DOWNLOAD_TO_PATH);
}

// 发起下载操作,这里的 URL 是示例图片地址,模拟下载图片场景
session.downloadToFile('https://example.com.png', downloadToFile)
  .then((response: rcp.Response) => {
    console.info(`Successfully received the response, statusCode: ${JSON.stringify(response.statusCode)}`);
  }).catch((err: BusinessError) => {
    console.error(`Failed, the error message is ${JSON.stringify(err)}`);
  });

拆一下这段逻辑:

  1. 访问路径是否存在
    • fileIo.accessSync(DOWNLOAD_TO_PATH) 为 true 表示路径已存在;
    • 示例里简单粗暴:存在就 rmdirSync 删掉(你可以根据实际情况做更精细的处理,比如只删同名文件)。
  2. 调用 session.downloadToFile(url, downloadToFile)
    • url:要下载的资源 URL;
    • downloadToFile:下载目标配置(这里是一个目录)。
  3. 根据 Promise 的结果:
    • then 分支:下载成功,打印状态码;
    • catch 分支:下载失败,打印错误信息。

✅ 适合场景:
静态文件分发、资源包更新、图片/视频/文档下载等。


四、上传实现:uploadFromFile + 自定义读文件类

上传这块多了一步:先从本地文件读内容,再交给 Remote Communication Kit 上传

1. 引入模块

import { rcp } from '@kit.RemoteCommunicationKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { fileIo } from '@kit.CoreFileKit';

2. 定义 Session 配置(带 TLS)

let SESSION_CONFIG: rcp.SessionConfiguration = {
  requestConfiguration: {
    transfer: {
      timeout: {
        connectMs: 6000
      }
    },
    security: {
      remoteValidation: 'skip',   // 同样,正式环境不建议 skip
      tlsOptions: {
        tlsVersion: 'TlsV1.3'
      }
    }
  }
};
  • 这里依然用的是 remoteValidation: 'skip'(示例方便)
  • tlsOptions.tlsVersion = 'TlsV1.3':强制指定使用 TLS 1.3 协议

3. 封装一个 FdReadFile 帮助类

class FdReadFile {
  readonly fd: number;

  constructor(fd: number) {
    this.fd = fd;
  }

  async read(buffer: ArrayBuffer): Promise<number> {
    return fileIo.read(this.fd, buffer);
  }
}

作用:

  • 持有一个文件描述符 fd
  • 暴露一个 read(buffer) 方法,读取数据到 ArrayBuffer
    → 方便 rcp.UploadFromFile 按统一接口来读数据。

4. 创建 Session 并打开文件

const session = rcp.createSession(SESSION_CONFIG);

const file = fileIo.openSync(
  '/data/storage/el1/bundle/entry_test/resources/resfile/upload_file.txt',
  fileIo.OpenMode.READ_ONLY
);

if (!file) {
  console.error('fileIo.openSync failed');
  return;
}
  • openSync 以只读模式打开本地文件;
  • 真实场景下路径换成你自己的沙箱路径。

5. 读取文件内容到缓冲区

const fdReadFile = new FdReadFile(file.fd);
const buffer = new ArrayBuffer(1024 * 1024); // 假设文件大小为 1MB
await fdReadFile.read(buffer);

这里示例简单粗暴:预分配了 1MB 的 buffer,假设文件不超过 1MB。
实际项目里可以做:

  • stat 得到真实大小再分配;
  • 或者按 chunk 循环读写(大文件分段上传)。

6. 调用 uploadFromFile 上传

await session.uploadFromFile(
  'https://httpbin.org/anything',
  new rcp.UploadFromFile(fdReadFile)
)
  .then((response: rcp.Response) => {
    console.info(`Upload succeeded: ${response}`);
  })
  .catch((err: BusinessError) => {
    console.error(`Upload failed: ${JSON.stringify(err)}`);
  });

说明:

  • 第一个参数是上传目标 URL;
  • 第二个参数 new rcp.UploadFromFile(fdReadFile)
    • RCP 内部会通过 fdReadFile.read() 读取数据并发送;
  • then / catch 分别处理上传成功 / 失败。

7. 关闭文件 & 会话

fileIo.closeSync(file.fd);
session.close();

千万别忘了关文件和会话,尤其是循环上传大量文件时,否则容易资源泄漏。


五、可以顺手再做的“增强版玩法”

基于这两个最小示例,其实很容易扩展出更实战的东西,比如:

  1. 支持断点续传的下载器
    • 配合 HTTP Range 头
    • 利用 Core File Kit 定位 offset,分段写入
  2. 大文件分片上传
    • 文件过大时,按固定 chunk 大小进行分片
    • 每片调用一次 uploadFromFile 或者在拦截器里加自定义逻辑
  3. 与拦截器配合
    • 在上传 / 下载中通过拦截器添加鉴权 Header(Token / 签名)
    • 打印每个文件的上传/下载耗时日志,用于性能分析
  4. 和 SecurityConfiguration / certificatePinning 打组合拳
    • 上传/下载敏感数据时开启证书校验、自定义 CA、证书 Pinning
    • 避免 remoteValidation: 'skip' 带来的中间人攻击风险

六、速记小抄(可以直接塞到 HarmonyOS 笔记里)

  • 下载(downloadToFile)
    • 核心方法:session.downloadToFile(url, downloadToFileConfig)
    • 搭配:fileIo.accessSync / fileIo.rmdirSync 管理本地目录
    • 典型配置:DownloadToFile.kind = 'folder' + path = 下载目录
  • 上传(uploadFromFile)
    • 核心方法:session.uploadFromFile(url, new rcp.UploadFromFile(reader))
    • 需要:自定义一个带 read(buffer) 方法的“文件读取器”,示例是 FdReadFile
    • 搭配:fileIo.openSync / fileIo.read / fileIo.closeSync
  • Session 配置
    • requestConfiguration.transfer.timeout.*:连通 & 传输超时
    • requestConfiguration.security.remoteValidation:证书校验策略(示例用 'skip',正式别这么干)
    • security.tlsOptions.tlsVersion = 'TlsV1.3':指定 TLS 版本
  • 设备支持
    • Phone / 2in1 / Tablet / Wearable
    • 5.1.1(19) 起新增 TV
posted @ 2025-12-13 20:23  遇到困难睡大觉哈哈  阅读(3)  评论(0)    收藏  举报