应用沙箱介绍
应用沙箱是一种以安全防护为目的的隔离机制,避免数据受到恶意路径穿越访问。在这种沙箱的保护机制下,应用可见的目录范围即为“应用沙箱目录”。
- 对于每个应用,系统会在内部存储空间映射出一个专属的“应用沙箱目录”,它是应用文件目录与一部分系统文件(应用运行必需的少量系统文件)所在的目录组成的集合。
- 应用沙箱限制了应用可见的数据范围。在“应用沙箱目录”中,应用仅能看到自己的应用文件以及少量的系统文件(应用运行必需的少量系统文件)。因此,本应用的文件也不为其他应用可见,从而保护了应用文件的安全。
- 应用可以在“应用文件目录”下保存和处理自己的应用文件;系统文件及其目录对于应用是只读的;而应用若需访问用户文件,则需要通过特定API同时经过用户的相应授权才能进行。
应用沙箱示意图
应用文件目录结构
在应用沙箱路径下,应用文件的目录结构如下图:
获取文件路径
鸿蒙开发提供应用上下文Context来获取应用中的基础信息,例如资源管理,当前应用信息,应用文件路径和文件分区等。实现对文件的操作必须利用上下文来获取沙箱路径下的目标文件目录,并拼接文件名组成完整url,以下是各路径获取一览:
//<路径前缀>/<加密等级>/base/haps/<module-name>/files HAP级别的应用文件路径
let context=getContext(this) as common.UIAbilityContext
//HAP级别各路径获取一览
let cacheDir = this.context.cacheDir;
let tempDir = this.context.tempDir;
let filesDir = this.context.filesDir;
let databaseDir = this.context.databaseDir;
let bundleCodeDir = this.context.bundleCodeDir;
let distributedFilesDir = this.context.distributedFilesDir;
let preferencesDir = this.context.preferencesDir;
let cloudFileDir = applicationContext.cloudFileDir;
//应用级别的文件路径获取:
let context =getContext(this) as common.UIAbilityContext
let applicationContext=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';
基本文件操作
先导入模块
import { fileIo as fs } from '@kit.CoreFileKit'
对文件进行读写,文件目录统计操作
let context=getContext(this) as common.UIAbilityContext
let filesDir=context.filesDir//<路径前缀>/<加密等级>/base/haps/<module-name>/files 应用沙箱路径 HAP级别的应用文件路径
//应用级别的文件路径获取:
//let context =getContext(this) as common.UIAbilityContext
//let applicationContext=context.getApplicationContext
function createFile():void{
let file=fs.openSync(filesDir+'/text.txt',fs.OpenMode.READ_WRITE|fs.OpenMode.CREATE)
let writeLen =fs.writeSync(file.fd,'Try to write str.')
console.info("the length of the str is "+writeLen)
let arrayBuffer=new ArrayBuffer(1024)
let readOptions:ReadOptions={
offset:0,
length:arrayBuffer.byteLength
}
let readLen=fs.readSync(file.fd,arrayBuffer,readOptions)
let buf=buffer.from(arrayBuffer,0,readLen)
console.info('the content of file '+buf.toString())
fs.closeSync(file)
readWriteFile()
getListFile()
}
function readWriteFile():void{
let srcFile=fs.openSync(filesDir+'/text.txt',fs.OpenMode.READ_WRITE |fs.OpenMode.CREATE)
let destFile =fs.openSync(filesDir+'/destFile.txt',fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE)
let bufSize=4096
let readSize=0
let buf =new ArrayBuffer(bufSize)
let readOptions:ReadOptions={
offset:readSize,//文件指针
length:bufSize
}
let readLen=fs.readSync(srcFile.fd,buf,readOptions)//返回读取的字节长度
console.info('the readLength of file '+readLen)
while(readLen>0){
readSize+=readLen//已读取的字符计数
let writeOptions:WriteOptions={
length:readLen
}
fs.writeSync(destFile.fd,buf,writeOptions)
readOptions.offset=readSize//将文件指针指向最后读取的字节
readLen=fs.readSync(srcFile.fd,buf,readOptions)
}
fs.closeSync(srcFile)
fs.closeSync(destFile)
}
function getListFile(): void {//输出当前目录下的指定后缀文件名,也可以不过滤
let listFileOption: ListFileOptions = {
recursion: false,
listNum: 0,
filter: {
suffix: [".png", ".jpg", ".txt"],
displayName: ["text*"],
fileSizeOver: 0,
lastModifiedAfter: new Date(0).getTime()
}
};//文件过滤选项,默认不过滤
let files = fs.listFileSync(filesDir);
for (let i = 0; i < files.length; i++) {
console.info(`The name of file: ${files[i]}`);
}
}