文件管理——应用文件
关注“极客马拉松”公众号,发送“仓库”可获得相关代码。
Core File Kit(文件基础服务)为开发者提供一套访问和管理应用文件和用户文件的能力。帮助用户更高效地管理、查找和备份各类文件,使用户能够轻松应对各种文件管理的需求。
概述
按文件所属分类 应用文件:文件属于应用本身,包括安装文件、缓存文件等。 用户文件:文件属于用户,包括用户私有的图片、视频等。 系统文件:与应用和用户无关的文件。包括公共库、设备文件等。
按文件位置分类 本地文件系统:本地设备或者外置存储设备(U盘、硬盘等) 分布式文件系统:提供跨设备文件访问能力。文件通过计算机网络存储在其他设备上。(手机访问电脑上的文件。主要是通过网络进行跨端访问。)
Core File Kit使用场景 ● 应用文件访问和文件分享。 ● 应用数据备份恢复。 ● 选择与保存用户文件。 ● 跨设备的文件访问和分享能力。
亮点/特征 沙箱隔离:隔离性、安全性。 应用分享:应用之间可以通过URI或者文件描述符FD的方式进行文件共享。
# 应用文件 概述 应用文件:文件所有者为应用,包括应用安装文件、应用资源文件、应用缓存文件等。 应用沙箱目录:应用沙箱是一种以安全防护为目的的隔离机制,避免数据受到恶意路径穿越访问。在这种沙箱的保护机制下,应用可见的目录范围即为“应用沙箱目录”。 ● 应用沙箱限制了应用可见的数据范围。 ● 应用可以在“应用文件目录”下保存和处理自己的应用文件;系统文件及其目录对于应用是只读的;而应用若需访问用户文件,则需要通过特定API同时经过用户的相应授权才能进行。
应用文件路径 常用的几个文件路径: base:应用在本设备上存放持久化数据的目录,子目录包含files/、cache/、temp/和haps/;随应用卸载而清理。 database:仅用于保存应用的私有数据库数据,主要包括数据库文件等。 files:应用通用文件路径,长期存储,随应用卸载而清理。 cache:应用缓存文件路径,可以自动清理。可以用于保存应用的缓存数据。 preferences:应用首选项文件路径,持久化,不适合存储大量数据。 temp:应用临时文件路径,运行时产生的文件,应用杀死后即清理。
应用文件的读写操作
/*
* 创建一个text文件, 写入 hello world
* */
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)
}
/*
* 读取出文件中的内容,存放到另一个文件中
* */
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。
//将沙箱路径转换为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"表示进行应用文件分享,开发示例如下。
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)
})