# 12.1:文件操作
ArkUI开发框架在 @ohos.ability.featureAbility
模块里提供了获取当前 Ability 上下文 Context
的 API,然后通过 Context
获取文件目录。在 @ohos.fileio
模块里提供了相关API对文件的读写操作,本节笔者简单介绍一下 OpenHarmony 应用安装后的文件沙盒目录获取方式以及文件的基本读写操作。
# 12.1.1:获取APP目录
OpenHarmony 应用安装后,系统会根据应用的 bundleName 创建相应的沙盒目录,APP的数据可以存储在该目录下,获取该目录需要借助 @ohos.ability.featureAbility
模块里的API获取当前 Ability
的上下文 Context
,然后调用 Context
的 getXXXDir()
方法获取相关目录,源码如下所示:
// featureAbility库提供的API
declare namespace featureAbility {
function getContext(): Context;
}
// Context提供的API
export interface Context extends BaseContext {
getFilesDir(callback: AsyncCallback<string>): void;
getCacheDir(callback: AsyncCallback<string>): void;
getExternalCacheDir(callback: AsyncCallback<string>): void;
getOrCreateLocalDir(callback: AsyncCallback<string>): void;
getOrCreateDistributedDir(callback: AsyncCallback<string>): void;
}
2
3
4
5
6
7
8
9
10
11
12
13
- getContext:获取当前
Ability
的上下文对象。 - getFilesDir:表示 APP 内部存储目录,可读写,随 APP 卸载时删除。
- getCacheDir:表示 APP 内部存储的缓存目录,可读写,但是随时可能被清楚,不保证持久性,一般用作下载临时目录或者缓存目录。
简单样例如下所示:
// 引入featureAbility库
import featureAbility from '@ohos.ability.featureAbility';
@Entry @Component struct Index {
build() {
Column({space: 10}) {
Button('获取根目录')
.onClick(() => {
featureAbility.getContext().getFilesDir((error, path) => {
console.log("files dir: " + path)
});
featureAbility.getContext().getCacheDir((error, path) => {
console.log("cache dir: " + path)
});
})
}
.padding(10)
.size({width: "100%", height: '100%'})
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
输出日志如下所示:
cache dir: /data/data/com.example.myapplication/cache
files dir: /data/data/com.example.myapplication/files
2
# 12.1.2:打开文件操作
对文件读写操作的第一步是打开文件,因为 @ohos.fileio
模块里提供的 read()
和 write()
方法需要传递一个文件描述符 fd ,所以先要调用 @ohos.fileio
模块里的 open()
方法打开文件:
declare function openSync(path: string, flags?: number, mode?: number): number;
path:待打开文件的绝对路径。
flags:打开文件的选项,必须指定如下选项中的一个,默认为 0o0 :
- 0o0:只读打开。
- 0o1:只写打开。
- 0o2:读写打开。
📢:同时,也可给定如下选项,以按位或的方式追加,默认不给定任何额外选项:
- 0o100:若文件不存在,则创建文件。使用该选项时必须指定第三个参数 mode。
- 0o200:如果追加了 0o100 选项,且文件已经存在,则出错。
- 0o1000:如果文件存在且以只写或读写的方式打开文件,则将其长度裁剪为零。
- 0o2000:以追加方式打开,后续写将追加到文件末尾。
- 0o4000:如果path指向 FIFO 、块特殊文件或字符特殊文件,则本次打开及后续 IO 进行非阻塞操作。
- 0o200000:如果path指向目录,则出错。
- 0o400000:如果path指向符号链接,则出错。
- 0o4010000:以同步IO的方式打开文件。
mode:若创建文件,则指定文件的权限,可给定如下权限,以按位或的方式追加权限,默认为0o666。
- 0o666:所有者具有读、写权限,所有用户组具有读、写权限,其余用户具有读、写权限。
- 0o700:所有者具有读、写及可执行权限。
- 0o400:所有者具有读权限。
- 0o200:所有者具有写权限。
- 0o100:所有者具有可执行权限。
- 0o070:所有用户组具有读、写及可执行权限。
- 0o040:所有用户组具有读权限。
- 0o020:所有用户组具有写权限。
- 0o010:所有用户组具有可执行权限。
- 0o007:其余用户具有读、写及可执行权限。
- 0o004:其余用户具有读权限。
- 0o002:其余用户具有写权限。
- 0o001:其余用户具有可执行权限。
简单样例如下所示:
private open(path: string) {
// 注意:0o102是0o2 | 0o100的结果。
let fd = fileio.openSync(path + "/" + this.fileName, 0o102, 0o666);
console.log("open file result: " + fd);
}
2
3
4
5
# 12.1.3:写入文件操作
对文件进行写数据操作,调用 @ohos.fileio
模块里提供的 writeXXX()
相关方法即可:
declare function write(fd: number, buffer: ArrayBuffer | string, callback: AsyncCallback<number>): void;
- fd:文件描述符。
- buffer:待写入内容。
- callback:写入结果回调。
简单样例如下所示:
private write(path: string) {
let fd = fileio.openSync(path + "/" + this.fileName, 0o102, 0o666);
fileio.write(fd, "你好,OpenHarmony", (error, length) => {
if(!error) {
console.log("write success, write length: " + length);
}
})
}
2
3
4
5
6
7
8
日志打印如下所示:
app Log: files dir: /data/data/com.example.myapplication/files
app Log: write success, write length: 20
2
# 12.1.4:读取文件操作
文件读取操作同样是使用 @ohos.fileio
模块里的 readXXX()
方法,代码如下所示:
declare function read(fd: number, buffer: ArrayBuffer, callback: AsyncCallback<ReadOut>): void;
- fd:文件描述符。
- buffer:缓存数组。
- callback:读取结果回调。
简单样例如下所示:
private read(path: string) {
let fd = fileio.openSync(path + "/" + this.fileName, 0o102, 0o666);
let buffer = new ArrayBuffer(4096);
fileio.read(fd, buffer, (error, data) => {
if(!error) {
let s = String.fromCodePoint.apply(null, new Uint8Array(data.buffer));
console.log("" + s);
let d = decodeURIComponent(escape(s));
console.log("read success, read content: " + d);
}
})
}
2
3
4
5
6
7
8
9
10
11
12
日志打印如下所示:
app Log: files dir: /data/data/com.example.myapplication/files // 路径
app Log: ä½ å¥½ï¼OpenHarmony // 乱码
app Log: read success, read content: 你好,OpenHarmony // 正常
2
3
📢:文件读取的时候,如果内容有中文,需要进行特殊处理,否则会有乱码。
# 12.1.5:文件拷贝操作
# 12.1.6:压缩解压缩操作
@ohos.zlib
模块提供了对文件的压缩和解压缩操作,需要对文件进行压缩或者解压缩的时候,直接调用该模块的相关 API 即可。
declare namespace zlib {
// 压缩文件
function zipFile(inFile:string, outFile:string, options: Options): Promise<void>;
// 解压文件
function unzipFile(inFile:string, outFile:string, options: Options): Promise<void>;
// 省略部分API
}
2
3
4
5
6
7
8
9
压缩文件
function zipFile(inFile:string, outFile:string, options: Options): Promise<void>;
1- inFile:需要压缩的文件。
- outFile:压缩到指定的zip文件。
- option:压缩的相关参数。
简单样例如下所示:
private zip(path: string) { let inFile = path + "/" + this.fileName; let outFile = path + "/test.zip"; zlib.zlib.zipFile(inFile, outFile, {}) .then((result) => { console.log(JSON.stringify(result)); }) .catch((error) => { console.log(JSON.stringify(error)); }) }
1
2
3
4
5
6
7
8
9
10
11解压缩文件
function unzipFile(inFile:string, outFile:string, options: Options): Promise<void>;
1- inFile:需要解压缩的文件。
- outFile:解压缩到目的目录。
- option:解压缩的相关参数。
简单样例如下所示:
private unzip(path: string) { let inFile = path + "/test.zip"; let outFile = path; zlib.zlib.unzipFile(inFile, outFile, {}) .then((result) => { console.log(JSON.stringify(result)); }) .catch((error) => { console.log(JSON.stringify(error)); }) }
1
2
3
4
5
6
7
8
9
10
11📢:目前测试发现,解压文件的时候,压缩包里的文件名不能包含特殊字符,比如:~ 和 @,否则会解压失败并报
17700101
的错误。
# 12.1.7:完整样例代码
文件进行读写操作的完整代码如下所示:
import featureAbility from '@ohos.ability.featureAbility';
import fileio from '@ohos.fileio';
import zlib from '@ohos.zlib';
@Entry @Component struct Index {
private fileName = "test.txt";
private rootDir: string = null;
build() {
Column({space: 10}) {
Button('获取根目录')
.onClick(() => {
featureAbility.getContext().getFilesDir((error, path) => {
console.log("files dir: " + path)
this.rootDir = path;
});
featureAbility.getContext().getCacheDir((error, path) => {
console.log("cache dir: " + path)
});
})
Button('打开文件')
.onClick(() => {
if(this.rootDir) {
this.open(this.rootDir);
}
})
Button('写入文件')
.onClick(() => {
if(this.rootDir) {
this.write(this.rootDir);
}
})
Button('读取文件')
.onClick(() => {
if(this.rootDir) {
this.read(this.rootDir);
}
})
Button('关闭文件')
.onClick(() => {
if(this.rootDir) {
this.close(this.rootDir);
}
})
Button('压缩文件')
.onClick(() => {
if(this.rootDir) {
this.zip(this.rootDir);
}
})
Button('解压缩文件')
.onClick(() => {
if(this.rootDir) {
this.unzip(this.rootDir);
}
})
}
.padding(10)
.size({width: "100%", height: '100%'})
}
private unzip(path: string) {
let inFile = path + "/test.zip";
let outFile = path;
zlib.zlib.unzipFile(inFile, outFile, {})
.then((result) => {
console.log(JSON.stringify(result));
})
.catch((error) => {
console.log(JSON.stringify(error));
})
}
private zip(path: string) {
let inFile = path + "/" + this.fileName;
let outFile = path + "/test.zip";
zlib.zlib.zipFile(inFile, outFile, {})
.then((result) => {
console.log(JSON.stringify(result));
})
.catch((error) => {
console.log(JSON.stringify(error));
})
}
private close(path: string) {
let fd = fileio.openSync(path + "/" + this.fileName, 0o102, 0o666);
fileio.closeSync(fd);
}
private open(path: string) {
let fd = fileio.openSync(path + "/" + this.fileName, 0o102, 0o666);
console.log("open file result: " + fd);
}
private read(path: string) {
let fd = fileio.openSync(path + "/" + this.fileName, 0o102, 0o666);
let buffer = new ArrayBuffer(4096);
fileio.read(fd, buffer, (error, data) => {
if(!error) {
let s = String.fromCodePoint.apply(null, new Uint8Array(data.buffer));
console.log("" + s);
let d = decodeURIComponent(escape(s));
console.log("read success, read content: " + d);
}
})
}
private write(path: string) {
let fd = fileio.openSync(path + "/" + this.fileName, 0o102, 0o666);
fileio.write(fd, "你好,OpenHarmony", (error, length) => {
if(!error) {
console.log("write success, write length: " + length);
}
})
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# 12.1.8:小结
本节简单介绍了 OpenHarmony 应用的目录获取和文件读写操作,有关 @ohos.fileio
模块里更多 API 的用法,读者自行查看一下源码,笔者就不多多介绍了。