前言

在OpenHarmony 5.0上,直接通过@ohos.file.fscopy相关的接口去将bundle内的文件拷贝到沙盒里,会出现拷贝后的文件体积大于原始文件且无法正常打开的问题。这是因为通过@ohos.resourceManagergetRawFdSync接口获取到的fd包含了resource的所有资源,需要通过指定的offsetlength拿到所需的资源buffer并写入到创建好的沙盒文件里才可以正确拷贝。

开发环境

系统版本: OpenHarmony 5.0.0.27

DevEco Studio版本: 4.1 Release (build:4.1.0.400)

SDK版本: 5.0.0.30_full-sdk

开发流程

这里预先将xxx.pdf文件内置与工程模块的rawfile资源目录下,目标是将其copy到沙盒路径/data/storage/el2/base/haps/entry/files/下。文件内置后即可参考如下示例:

import fs, { ReadOptions } from '@ohos.file.fs';

// 将bundle下的PDF文件copy到沙盒
let resourceManager = getContext(this).resourceManager
// 读取bundle资源
let bundleFile = resourceManager.getRawFdSync('xxx.pdf')
// 获取bundle buffer
let bundleBuffer = new ArrayBuffer(4096)
// 获取bundle offset
let bundleOffset = bundleFile.offset
// 获取bundle length
let bundleLength = bundleFile.length
// 创建readOption
let readOption: ReadOptions = {
  offset: bundleOffset,
  length: bundleLength > bundleBuffer.byteLength ? 4096 : bundleLength
}
// 创建沙盒文件
let filePath = getContext(this).filesDir + '/' + 'xxx.pdf'
let file = fs.openSync(filePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE | fs.OpenMode.TRUNC)
// 向沙盒文件写入数据
while (true) {
  // 读取buffer内容
  let readLength = fs.readSync(bundleFile.fd, bundleBuffer, readOption)
  // 写入buffer内容
  fs.writeSync(file.fd, bundleBuffer, { length: readLength })
  // 分段写入直至写完
  if (readLength < 4096) {
    break;
  }
  // 计算剩余写入大小
  bundleLength -= readLength
  readOption.offset! += readLength
  readOption.length = bundleLength > bundleBuffer.byteLength ? 4096 : bundleLength
}
fs.close(file)
Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐