【HarmonyOS NEXT】鸿蒙将资源文件夹 Resource-RawFile 下的文件存放到沙箱目录下
一、问题背景
应用开发中,我们经常会遇到一些文件原先是放在资源文件夹 rawfile 下,但是逻辑处理时,需要转移到本地沙箱才能操作。这种情况下,就需要将将资源文件夹 Resource-RawFile 下的文件存放到沙箱目录下。
二、鸿蒙资源文件和沙箱的概念
在鸿蒙中,应用仅能保存文件到“应用文件目录”下,根据目录的使用规范和注意事项来选择将数据保存到不同的子目录中。
这样的设定与安卓和苹果目前一致。应用沙箱的概念,可以保证数据访问的安全性。
在鸿蒙系统中,文件存储分为不同的域,如应用内部存储(应用私有目录)和外部存储(公共目录等)。应用内部存储是应用私有的,其他应用通常无法访问。外部存储可以在用户授权的情况下被多个应用访问。
注意:
不要使用绝对路径拼接系统文件路径,否则可能导致后续应用版本因应用文件路径变化导致不兼容问题。应该是用 context 去动态获取。
而 rawfile 是一种资源文件类型,通常在应用开发过程中作为原始文件被打包进应用的资源目录。它在 APK(安卓应用安装包)或者鸿蒙应用安装包(HAP)中是只读的。
三、解决方案思路
1.首先我们需要通过 getRawFileContentSync 读取 rawfile 下目标文件的内容 val
let val: Uint8Array = context.resourceManager.getRawFileContentSync("test.zip");
复制代码
2.之后创建本地沙箱的文件对象 fileTarget
let pathDir: string = context.filesDir; // /data/storage/el2/base/haps/entry/files console.info(this.TAG, "pathDir: " + pathDir); // 待拷贝文件沙箱路径 let filePath: string = pathDir + '/test.zip'; console.info(this.TAG, "filePath: " + filePath); // 若文件不存在,则创建文件。 let fileTarget = fs.openSync(filePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
复制代码
3.将 val 目标文件内容写入文件对象即可
let writeLen = fs.writeSync(fileTarget.fd, val.buffer as ArrayBuffer);
复制代码
最后记得关闭 fs
fs.closeSync(fileTarget);
复制代码
完整源码
import { common } from '@kit.AbilityKit';import { BusinessError } from '@kit.BasicServicesKit';import { fileIo as fs } from '@kit.CoreFileKit';
@Entry@Componentstruct SandboxPage { private TAG: string = "SandboxPage";
onCopyRawFileToLocal = ()=>{ let context = getContext(this) as common.UIAbilityContext; // 获取设备A的UIAbilityContext信息 try { let val: Uint8Array = context.resourceManager.getRawFileContentSync("test.zip"); console.info(this.TAG, "getRawFileContentSync done"); let pathDir: string = context.filesDir; // /data/storage/el2/base/haps/entry/files console.info(this.TAG, "pathDir: " + pathDir); // 待拷贝文件沙箱路径 let filePath: string = pathDir + '/test.zip'; console.info(this.TAG, "filePath: " + filePath); // 若文件不存在,则创建文件。 let file = fs.openSync(filePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); console.info(this.TAG, "file done"); let writeLen = fs.writeSync(file.fd, val.buffer as ArrayBuffer); console.info(this.TAG, "write data to file succeed and size is:" + writeLen); fs.closeSync(file); } catch (error) { let code = (error as BusinessError).code; let message = (error as BusinessError).message; console.error(this.TAG,`getRawFileContentSync failed, error code: ${code}, message: ${message}.`); }
}
build() { RelativeContainer() { Text("点击拷贝zip到本地沙箱下") .id('SandboxPageHelloWorld') .fontSize(50) .fontWeight(FontWeight.Bold) .alignRules({ center: { anchor: '__container__', align: VerticalAlign.Center }, middle: { anchor: '__container__', align: HorizontalAlign.Center } }) .onClick(this.onCopyRawFileToLocal) } .height('100%') .width('100%') }}
复制代码
验证 zip 拷贝成功:1. IDE 右下角找到 Device File Browser
2.根据你的 app 包名,找到 zip 的位置
评论