关注“极客马拉松”,发送“仓库”可获得相关代码。
Core File Kit(文件基础服务)为开发者提供一套访问和管理应用文件和用户文件的能力。帮助用户更高效地管理、查找和备份各类文件,使用户能够轻松应对各种文件管理的需求。
概述
按文件所属分类
应用文件:文件属于应用本身,包括安装文件、缓存文件等。
用户文件:文件属于用户,包括用户私有的图片、视频等。
系统文件:与应用和用户无关的文件。包括公共库、设备文件等。
按文件位置分类
本地文件系统:本地设备或者外置存储设备(U盘、硬盘等)
分布式文件系统:提供跨设备文件访问能力。文件通过计算机网络存储在其他设备上。(手机访问电脑上的文件。主要是通过网络进行跨端访问。)
Core File Kit使用场景
● 应用文件访问和文件分享。
● 应用数据备份恢复。
● 选择与保存用户文件。
● 跨设备的文件访问和分享能力。
亮点/特征
沙箱隔离:隔离性、安全性。
应用分享:应用之间可以通过URI或者文件描述符FD的方式进行文件共享。
应用文件
概述
应用文件:文件所有者为应用,包括应用安装文件、应用资源文件、应用缓存文件等。
应用沙箱目录
应用沙箱是一种以安全防护为目的的隔离机制,避免数据受到恶意路径穿越访问。在这种沙箱的保护机制下,应用可见的目录范围即为“应用沙箱目录”。
● 应用沙箱限制了应用可见的数据范围。
● 应用可以在“应用文件目录”下保存和处理自己的应用文件;系统文件及其目录对于应用是只读的;而应用若需访问用户文件,则需要通过特定API同时经过用户的相应授权才能进行。
应用文件路径
常用的几个文件路径:
files:应用通用文件路径,长期存储,随应用卸载而清理。
cache:应用缓存文件路径,可以自动清理。可以用于保存应用的缓存数据。
preferences:应用首选项文件路径,持久化,不适合存储大量数据。
temp:应用临时文件路径,运行时产生的文件,应用杀死后即清理。
应用文件的读写操作
context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
/*
1. 创建一个text文件, 写入 hello world
2. */
createFile() {
let fileDir = this.context.filesDir
let file = fs.openSync(fileDir + '/test.text', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE)
let writeLen = fs.writeSync(file.fd, 'hello world')
console.log("写入的长度", writeLen)
fs.closeSync(file.fd)
}
/*
3. 读取出文件中的内容,存放到另一个文件中
4. */
readFile() {
let fileDir = this.context.filesDir
let file = fs.openSync(fileDir + '/test.text', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE)
let newFile = fs.openSync(fileDir + '/newFile.text', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE)
let arrayBuffer = new ArrayBuffer(4096)
let readSize = 0
let readOption: ReadOptions = {
offset: readSize, // 偏移量
length: arrayBuffer.byteLength //长度
}
let readLen = fs.readSync(file.fd, arrayBuffer, readOption)
if (readLen > 0) {
let writeOption: WriteOptions = {
length: readLen
}
fs.writeSync(newFile.fd, arrayBuffer, writeOption)
readSize = readLen + readSize
readOption.offset = readSize
readLen = fs.readSync(file.fd, arrayBuffer, readOption)
}
fs.closeSync(file.fd)
fs.closeSync(newFile.fd)
}
//获取文件列表
getFileList() {
let listFileOption: ListFileOptions = {
recursion: true, //true返回相对路径, false只返回文件名,且只返回一级目录
listNum: 0
}
let files = fs.listFileSync(this.context.filesDir, listFileOption)
for (let i = 0; i < files.length; i++) {
console.log("文件名:" + files[i])
}
}
//创建目录, 注意在创建目录时,创建以及存在的目录是会报错。需要进行检测
createDir(path: string) {
if (fs.accessSync(path, fs.AccessModeType.EXIST)) {
console.log("目录已经存在")
return
}
fs.mkdirSync(path, true)
}
//以流的形式读写文件
async copyFileWithReadable() {
// 创建并打开输入文件流
let inputStream = fs.createStreamSync(this.context.filesDir + '/test.text', 'r+')
//创建并打开输出文件流
let outputStream = fs.createStreamSync(this.context.filesDir + '/destFile.txt', "w+");
let bufSize = 4096
let readSize = 0
let buf = new ArrayBuffer(bufSize)
let readOptions: ReadOptions = {
offset: readSize,
length: bufSize
}
let readLen = await inputStream.readSync(buf, readOptions)
readSize = readSize + readLen
while (readLen > 0){
const writeBuf = readLen < bufSize ? buf.slice(0, readLen) : buf
outputStream.writeSync(writeBuf)
readOptions.offset = readSize
readLen = await inputStream.read(buf, readOptions)
readSize = readSize + readLen
}
inputStream.closeSync()
outputStream.closeSync()
}
应用文件分享
应用文件分享是应用之间通过分享URI或文件描述符FD的方式,进行文件分享的过程。
基于URI和FD分享方式,应用可分享单个文件,可以对文件进行读写操作。不过由于FD分享的文件关闭FD后,无法在打开分享文件。因此推荐使用基于URI的分享方式。
文件URI规范
格式:file:///
file:文件URI的标志(固定写法)
bundleName:该文件资源的宿主(包名)
path:文件资源在应用沙箱中的路径
分享文件给其他应用
1、获取要分享的文件沙箱路径,并转换为文件URI。
let sharePath = this.context.filesDir + '/test.txt'
//将沙箱路径转换为uri
let uri = fileUri.getUriFromPath(sharePath)
console.log("uri路径", uri)
2、设置获取文件的权限以及选择要分享的应用。
分享文件给其他应用需要使用startAbility接口,将获取到的URI填充在want的参数URI中,标注URI的文件类型,type字段可参考want属性,并通过设置want的flag来设置对应的读写权限,action字段配置为"ohos.want.action.sendData"表示进行应用文件分享,开发示例如下。
//隐式want
let want: Want = {
//设置读写权限
flags: wantConstant.Flags.FLAG_AUTH_READ_URI_PERMISSION | wantConstant.Flags.FLAG_AUTH_WRITE_URI_PERMISSION,
action: 'ohos.want.action.sendData', //表示要执行的通用操作(如:查看、分享、应用详情)。
uri: uri,
type: 'text/plain' //分享的文件类型
}
this.context.startAbility(want)
.then((data) => {
console.log("startAbility成功", data)
})
.catch((error: BusinessError) => {
console.error("startAbility失败", error)
})