沙箱路径
参考网址
[https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/app-sandbox-directory-V5](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/app-sandbox-directory-V5)应用沙箱目录与应用沙箱路径
**图1 应用沙箱文件访问关系**本应用的文件也不为其他应用可见,从而保护了应用文件的安全。
应用若需访问用户文件,则需要通过特定API同时经过用户的相应授权才能进行
应用文件目录与应用文件路径
- 一级目录data/:代表应用文件目录。
- 二级目录storage/:代表本应用持久化文件目录。
- 三级目录el1/、el2/:代表不同文件加密类型。
- el1,设备级加密区:设备开机后即可访问的数据区。
- el2,用户级加密区:设备开机后,若处于无密码状态,可直接访问;若处于有密码状态,则需要设备首次密码解锁之后,才能够访问的加密数据区。开发者可通过监听COMMON_EVENT_USER_UNLOCKED事件感知设备首次密码解锁完成。应用如无特殊需要,应将数据存放在el2加密目录下,以尽可能保证数据安全。但是对于某些场景,一些应用文件需要在用户解锁前就可被访问,例如时钟、闹铃、壁纸等,此时应用需要将这些文件存放到设备级加密区(el1)。切换应用文件加密类型目录的方法请参见获取和修改加密分区。
应用文件路径具体说明及生命周期如下表所示。
表1 应用文件路径详细说明
目录名 | Context属性名称 | 类型 | 说明 |
---|---|---|---|
bundle | bundleCodeDir | 安装文件路径 | 应用安装后的App的HAP资源包所在目录;随应用卸载而清理。不能拼接路径访问资源文件,请使用资源管理接口访问资源。可以用于存储应用的代码资源数据,主要包括应用安装的HAP资源包、可重复使用的库文件以及插件资源等。此路径下存储的代码资源数据可以被用于动态加载。 |
base | NA | 本设备文件路径 | 应用在本设备上存放持久化数据的目录,子目录包含files/、cache/、temp/和haps/;随应用卸载而清理。 |
database | databaseDir | 数据库路径 | 应用在el2加密条件下存放通过分布式数据库服务操作的文件目录;随应用卸载而清理。仅用于保存应用的私有数据库数据,主要包括数据库文件等。此路径下仅适用于存储分布式数据库相关文件数据。 |
distributedfiles | distributedFilesDir | 分布式文件路径 | 应用在el2加密条件下存放分布式文件的目录,应用将文件放入该目录可分布式跨设备直接访问;随应用卸载而清理。可以用于保存应用分布式场景下的数据,主要包括应用多设备共享文件、应用多设备备份文件、应用多设备群组协助文件。此路径下存储这些数据,使得应用更加适合多设备使用场景。 |
files | filesDir | 应用通用文件路径 | 应用在本设备内部存储上通用的存放默认长期保存的文件路径;随应用卸载而清理。可以用于保存应用的任何私有数据,主要包括用户持久性文件、图片、媒体文件以及日志文件等。此路径下存储这些数据,使得数据保持私有、安全且持久有效。 |
cache | cacheDir | 应用缓存文件路径 | 应用在本设备内部存储上用于缓存下载的文件或可重新生成的缓存文件的路径,应用cache目录大小超过配额或者系统空间达到一定条件,自动触发清理该目录下文件;用户通过系统空间管理类应用也可能触发清理该目录。应用需判断文件是否仍存在,决策是否需重新缓存该文件。可以用于保存应用的缓存数据,主要包括离线数据、图片缓存、数据库备份以及临时文件等。此路径下存储的数据可能会被系统自动清理,因此不要存储重要数据。 |
preferences | preferencesDir | 应用首选项文件路径 | 应用在本设备内部存储上通过数据库API存储配置类或首选项的目录;随应用卸载而清理。详见通过用户首选项实现数据持久化。可以用于保存应用的首选项数据,主要包括应用首选项文件以及配置文件等。此路径下仅适用于存储小量数据。 |
temp | tempDir | 应用临时文件路径 | 应用在本设备内部存储上仅在应用运行期间产生和需要的文件,应用退出后即清理。可以用于保存应用的临时生成的数据,主要包括数据库缓存、图片缓存、临时日志文件、以及下载的应用安装包文件等。此路径下存储使用后即可删除的数据。 |
获取应用文件路径
[https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/application-context-stage-V5#](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/application-context-stage-V5#)基类Context提供了获取应用文件路径的能力,ApplicationContext、AbilityStageContext、UIAbilityContext和ExtensionContext均继承该能力。应用文件路径属于应用沙箱路径,具体请参见应用沙箱目录。
属性 | 路径 |
---|---|
bundleCodeDir | <路径前缀>/el1/bundle |
cacheDir | <路径前缀>/<加密等级>/base/cache |
filesDir | <路径前缀>/<加密等级>/base/files |
preferencesDir | <路径前缀>/<加密等级>/base/preferences |
tempDir | <路径前缀>/<加密等级>/base/temp |
databaseDir | <路径前缀>/<加密等级>/database |
distributedFilesDir | <路径前缀>/el2/distributedFiles |
cloudFileDir12+ | <路径前缀>/el2/cloud |
示例代码如下所示。
import { common } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { promptAction } from '@kit.ArkUI';
const TAG: string = '[Page_Context]';
const DOMAIN_NUMBER: number = 0xFF00;
@Entry
@Component
struct Page_Context {
private context = getContext(this) as common.UIAbilityContext;
build() {
Column() {
//...
List({ initialIndex: 0 }) {
ListItem() {
Row() {
//...
}
.onClick(() => {
let applicationContext = this.context.getApplicationContext();
let cacheDir = applicationContext.cacheDir;
let tempDir = applicationContext.tempDir;
let filesDir = applicationContext.filesDir;
let databaseDir = applicationContext.databaseDir;
let bundleCodeDir = applicationContext.bundleCodeDir;
let distributedFilesDir = applicationContext.distributedFilesDir;
let preferencesDir = applicationContext.preferencesDir;
let cloudFileDir = applicationContext.cloudFileDir;
// 获取应用文件路径
let filePath = tempDir + 'test.txt';
hilog.info(DOMAIN_NUMBER, TAG, `filePath: ${filePath}`);
if (filePath !== null) {
promptAction.showToast({
message: filePath
});
}
})
}
//...
}
//...
}
//...
}
}
沙箱文件写入操作:
[https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/app-file-access-V5](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/app-file-access-V5)
// rawfile中的文件拷贝到沙箱
// let uint8Array: Uint8Array = this.context.resourceManager.getRawFileContentSync("test.txt");
// let bf = buffer.from(uint8Array).buffer;
// let textPath = this.filesDir + "/txt"
// try {
// // fs.mkdirSync(textPath)
// let zipPath = textPath + "/test.txt"
//
// const fsOpen = fs.openSync(zipPath,
// fs.OpenMode.READ_WRITE | fs.OpenMode.READ_ONLY | fs.OpenMode.CREATE | fs.OpenMode.TRUNC)
// let destFile = fs.writeSync(fsOpen.fd, bf);
// // 写入完毕后关闭文件,因为在上一步文件在开启中
// fs.close(destFile)
// } catch (e) {
// promptAction.showToast({
// message:
// JSON.stringify(e)
// })
// }
//
// return
// 往沙箱中写入数据
// 文件不存在时创建并打开文件,文件存在时打开文件
let file = fs.openSync(this.filesDir + '/test3.txt', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
// 写入一段内容至文件
let writeLen = fs.writeSync(file.fd, "Try to write str.");
console.info("The length of str is: " + writeLen);
// 创建一个大小为1024字节的ArrayBuffer对象,用于存储从文件中读取的数据
let arrayBuffer = new ArrayBuffer(1024);
// 设置读取的偏移量和长度
let readOptions: ReadOptions = {
offset: 0,
length: arrayBuffer.byteLength
};
// 读取文件内容到ArrayBuffer对象中,并返回实际读取的字节数
let readLen = fs.readSync(file.fd, arrayBuffer, readOptions);
// 将ArrayBuffer对象转换为Buffer对象,并转换为字符串输出
let buf = buffer.from(arrayBuffer, 0, readLen);
console.info("the content of file: " + buf.toString());
// 关闭文件
fs.closeSync(file);