鸿蒙ArkTS文件管理:fileIo 文件读写与目录操作


一、引言
文件管理是应用开发的基础能力。无论是缓存数据、导出文件、读取配置文件,还是处理用户上传的文档,都离不开文件系统操作。HarmonyOS 提供了强大的 fileIo 模块(@kit.CoreFileKit),支持文件的创建、读写、删除、复制、移动,以及目录的遍历、创建等操作。
本文将以一个文件管理器风格的演示页面为主线,深入讲解 fileIo 文件操作的核心 API,通过大量代码示例帮助读者掌握文件管理的开发技能。
二、文件系统基础
2.1 应用沙箱目录
HarmonyOS 应用运行在沙箱环境中,每个应用有自己的私有目录。常用目录如下:
| 目录 | 获取方式 | 用途 |
|---|---|---|
| 应用文件目录 | context.filesDir |
应用私有文件 |
| 应用缓存目录 | context.cacheDir |
缓存文件 |
| 应用数据库目录 | context.databaseDir |
数据库文件 |
| 应用偏好目录 | context.preferencesDir |
Preferences 文件 |
| 应用临时目录 | context.tempDir |
临时文件 |
const ctx = getContext(this) as common.UIAbilityContext;
const filesDir = ctx.filesDir; // 应用文件目录
const cacheDir = ctx.cacheDir; // 缓存目录
const databaseDir = ctx.databaseDir; // 数据库目录
2.2 文件路径
HarmonyOS 文件路径使用 file:// 协议或直接使用绝对路径:
// 绝对路径
const filePath = `${ctx.filesDir}/demo.txt`;
// file:// 协议
const fileUrl = `file://${ctx.filesDir}/demo.txt`;
三、fileIo 核心 API
3.1 文件打开与创建
import { fileIo as fs } from '@kit.CoreFileKit';
// 打开文件(不存在则创建)
const file = fs.openSync('/path/to/file.txt', fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE);
// 使用文件描述符
const fd = file.fd;
// 关闭文件
fs.closeSync(file);
代码说明:
fs.openSync(path, mode)同步打开文件,返回 File 对象。OpenMode枚举控制打开方式:READ_ONLY:只读。WRITE_ONLY:只写。READ_WRITE:读写。CREATE:不存在则创建。TRUNC:清空内容。APPEND:追加写入。
file.fd获取文件描述符。fs.closeSync(file)关闭文件,释放资源。
3.2 文件写入
// 写入字符串
const file = fs.openSync(path, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE);
fs.writeSync(file.fd, 'Hello HarmonyOS!');
fs.closeSync(file);
代码说明:
fs.writeSync(fd, data)同步写入数据,data 可以是字符串或 ArrayBuffer。- 写入后必须关闭文件,确保数据落盘。
3.3 文件读取
// 读取文本文件
const file = fs.openSync(path, fs.OpenMode.READ_ONLY);
const buffer = new ArrayBuffer(1024);
const readLen = fs.readSync(file.fd, buffer);
const text = String.fromCharCode(...new Uint8Array(buffer).slice(0, readLen));
fs.closeSync(file);
代码说明:
fs.readSync(fd, buffer)同步读取数据到 buffer。- 返回实际读取的字节数。
- 通过
Uint8Array和String.fromCharCode将二进制转换为文本。
3.4 文件信息
// 获取文件状态
const stat = fs.statSync(path);
console.info(`大小: ${stat.size} 字节`);
console.info(`是否目录: ${stat.isDirectory()}`);
console.info(`是否文件: ${stat.isFile()}`);
console.info(`修改时间: ${stat.mtime}`);
四、目录操作
4.1 创建目录
// 创建单级目录
fs.mkdirSync('/path/to/newDir');
// 递归创建多级目录
fs.mkdirSync('/path/to/a/b/c', true);
4.2 遍历目录
// 列出目录下所有文件名
const names = fs.listFileSync('/path/to/dir');
names.forEach((name) => {
console.info(`文件名: ${name}`);
});
4.3 删除目录
// 删除空目录
fs.rmdirSync('/path/to/emptyDir');
// 递归删除目录
fs.rmdirSync('/path/to/dir', true);
五、实战代码:文件管理器页面
下面我们实现一个文件管理器风格的演示页面,包含工具栏、文件列表和文件操作。
5.1 定义数据结构
interface FileRow {
name: string;
size: string;
type: string;
icon: string;
}
代码说明:
FileRow 接口描述文件列表中的一行数据:
name:文件名。size:文件大小(格式化后的字符串)。type:文件类型(目录/文件)。icon:图标(📁 或 📄)。
5.2 组件状态定义
@Entry
@Component
struct FilePage {
@State files: FileRow[] = [];
@State currentPath: string = '';
private baseDir: string = '';
aboutToAppear(): void {
const ctx = getContext(this) as common.UIAbilityContext;
this.baseDir = ctx.filesDir;
this.currentPath = this.baseDir;
this.refreshFiles();
}
代码说明:
aboutToAppear中获取应用文件目录作为初始路径。- 调用
refreshFiles加载文件列表。
5.3 刷新文件列表
refreshFiles(): void {
try {
const list = fs.listFileSync(this.currentPath);
this.files = list.map((name: string) => {
const stat = fs.statSync(`${this.currentPath}/${name}`);
return {
name: name,
size: stat.size > 1024 ? `${(stat.size / 1024).toFixed(1)} KB` : `${stat.size} B`,
type: stat.isDirectory() ? '目录' : '文件',
icon: stat.isDirectory() ? '📁' : '📄'
};
});
} catch (e) {
promptAction.showToast({ message: `读取失败: ${JSON.stringify(e)}` });
}
}
代码说明:
refreshFiles 是文件列表加载的核心:
-
列出文件:
fs.listFileSync(this.currentPath)列出当前目录下所有文件名。 -
映射为数据:
map遍历文件名,对每个文件:fs.statSync(path)获取文件状态。- 格式化大小:大于 1KB 显示为 KB,否则显示为 B。
- 判断类型:
isDirectory()区分目录和文件。 - 设置图标:目录用 📁,文件用 📄。
-
异常处理:目录不存在或权限不足时捕获异常并提示。
5.4 创建文件
createFile(): void {
try {
const f = fs.openSync(`${this.currentPath}/demo_${Date.now()}.txt`, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE);
fs.writeSync(f.fd, 'Hello HarmonyOS FileIO!\n这是一段写入文件的内容。');
fs.closeSync(f);
this.refreshFiles();
promptAction.showToast({ message: '文件创建成功' });
} catch (e) {
promptAction.showToast({ message: `创建失败: ${JSON.stringify(e)}` });
}
}
代码说明:
createFile 演示了文件创建和写入的完整流程:
-
打开文件:
fs.openSync使用CREATE | READ_WRITE模式,文件不存在则创建。文件名使用Date.now()保证唯一。 -
写入内容:
fs.writeSync(f.fd, content)写入文本内容。 -
关闭文件:
fs.closeSync(f)关闭文件,确保数据落盘。 -
刷新列表:调用
refreshFiles更新 UI。 -
异常处理:捕获并提示创建失败。
5.5 创建目录
createDir(): void {
try {
fs.mkdirSync(`${this.currentPath}/newDir_${Date.now()}`);
this.refreshFiles();
promptAction.showToast({ message: '目录创建成功' });
} catch (e) {
promptAction.showToast({ message: `创建失败: ${JSON.stringify(e)}` });
}
}
代码说明:
createDir 创建新目录,使用 Date.now() 保证目录名唯一,创建后刷新列表。
5.6 删除文件
deleteItem(name: string): void {
try {
const stat = fs.statSync(`${this.currentPath}/${name}`);
if (stat.isDirectory()) {
fs.rmdirSync(`${this.currentPath}/${name}`);
} else {
fs.unlinkSync(`${this.currentPath}/${name}`);
}
this.refreshFiles();
promptAction.showToast({ message: `已删除 ${name}` });
} catch (e) {
promptAction.showToast({ message: `删除失败: ${JSON.stringify(e)}` });
}
}
代码说明:
deleteItem 演示了删除操作:
- 判断类型:通过
stat.isDirectory()判断是目录还是文件。 - 删除目录:
fs.rmdirSync删除目录。 - 删除文件:
fs.unlinkSync删除文件。 - 刷新列表:更新 UI 并提示结果。
5.7 构建 UI
build() {
Column() {
// 顶部标题
Column() {
Text('FILE')
.fontSize(12)
.fontColor('#B8C0CC')
.letterSpacing(6)
Text('文件管理')
.fontSize(26)
.fontWeight(FontWeight.Bold)
.fontColor(Color.White)
.margin({ top: 6 })
Text('fileIo · 文件读写与目录操作')
.fontSize(12)
.fontColor('#B8C0CC')
.margin({ top: 6 })
}
.width('100%')
.padding({ top: 44, bottom: 22 })
.backgroundColor('#2F3542')
// 工具栏
Row({ space: 10 }) {
Button('📄 新建文件')
.height(38)
.layoutWeight(1)
.fontSize(12)
.fontColor(Color.White)
.backgroundColor('#57606F')
.borderRadius(6)
.onClick(() => { this.createFile(); })
Button('📁 新建目录')
.height(38)
.layoutWeight(1)
.fontSize(12)
.fontColor(Color.White)
.backgroundColor('#57606F')
.borderRadius(6)
.onClick(() => { this.createDir(); })
Button('🔄 刷新')
.height(38)
.layoutWeight(1)
.fontSize(12)
.fontColor('#57606F')
.backgroundColor(Color.White)
.borderRadius(6)
.border({ width: 1, color: '#57606F' })
.onClick(() => { this.refreshFiles(); })
}
.width('100%')
.padding(12)
.backgroundColor('#F1F2F6')
// 当前路径
Text(`📂 ${this.currentPath}`)
.fontSize(11)
.fontColor('#747D8C')
.width('100%')
.padding({ left: 16, right: 16, top: 8 })
.maxLines(1)
.textOverflow({ overflow: TextOverflow.MiddleTruncation })
// 文件列表表格
List({ space: 2 }) {
ForEach(this.files, (file: FileRow) => {
ListItem() {
Row({ space: 12 }) {
Text(file.icon)
.fontSize(22)
Column({ space: 3 }) {
Text(file.name)
.fontSize(14)
.fontWeight(FontWeight.Medium)
.fontColor('#2F3542')
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
Text(`${file.type} · ${file.size}`)
.fontSize(11)
.fontColor('#747D8C')
}
.alignItems(HorizontalAlign.Start)
.layoutWeight(1)
Button('删除')
.fontSize(11)
.fontColor('#FF4757')
.backgroundColor('#FFF0F0')
.borderRadius(6)
.onClick(() => { this.deleteItem(file.name); })
}
.width('100%')
.padding(12)
.backgroundColor(Color.White)
.border({ width: { bottom: 1 }, color: '#F1F2F6' })
}
})
}
.layoutWeight(1)
.width('100%')
// 底部返回
Button('返回首页')
.width('100%')
.height(46)
.fontSize(15)
.fontColor(Color.White)
.backgroundColor('#2F3542')
.borderRadius(0)
.onClick(() => { router.back(); })
}
.width('100%')
.height('100%')
.backgroundColor('#F1F2F6')
}
代码说明:
文件管理器页面结构:
-
顶部标题:深灰色背景的标题区。
-
工具栏:三个操作按钮(新建文件、新建目录、刷新),深灰色按钮配白色文字,刷新按钮为描边样式。
-
当前路径:显示当前所在目录路径,超出部分中间截断。
-
文件列表:
List组件渲染文件列表,每行包含图标、文件名、类型和大小,右侧是删除按钮。 -
底部返回:全宽按钮返回首页。
六、文件读写高级用法
6.1 追加写入
const file = fs.openSync(path, fs.OpenMode.APPEND | fs.OpenMode.READ_WRITE);
fs.writeSync(file.fd, '追加的内容');
fs.closeSync(file);
6.2 文件复制
fs.copyFileSync(srcPath, destPath);
6.3 文件移动/重命名
fs.renameSync(oldPath, newPath);
6.4 文件截断
fs.truncateSync(path, 100); // 截断到 100 字节
6.5 判断文件是否存在
import { common } from '@kit.AbilityKit';
function isExist(path: string): boolean {
try {
fs.statSync(path);
return true;
} catch (e) {
return false;
}
}
七、异步文件操作
对于大文件操作,推荐使用异步 API 避免阻塞主线程:
async function readLargeFile(path: string): Promise<string> {
const file = fs.openSync(path, fs.OpenMode.READ_ONLY);
try {
const stat = fs.statSync(path);
const buffer = new ArrayBuffer(stat.size);
await fs.read(file.fd, buffer);
return String.fromCharCode(...new Uint8Array(buffer));
} finally {
fs.closeSync(file);
}
}
八、最佳实践
8.1 资源管理
文件操作完成后务必关闭文件(closeSync),避免文件描述符泄漏。
8.2 路径安全
拼接路径时注意分隔符,推荐使用模板字符串:
const filePath = `${this.currentPath}/${name}`;
8.3 大文件异步
大文件读写使用异步 API,避免阻塞 UI 线程。
8.4 异常处理
文件操作可能因权限、路径不存在等原因失败,务必使用 try...catch 处理。
九、常见问题
9.1 文件写入不生效
原因:写入后没有关闭文件,数据未落盘。
解决:写入后调用 closeSync。
9.2 路径不存在报错
原因:目录或文件不存在。
解决:操作前检查路径,或使用 CREATE 模式自动创建。
9.3 权限不足
原因:访问了无权限的目录。
解决:只操作应用沙箱内的目录,或申请相应权限。
十、总结
本文深入讲解了 HarmonyOS 文件管理技术,通过一个文件管理器风格的演示页面实战演示了文件创建、写入、删除、目录操作等核心能力。
核心要点回顾:
- 应用沙箱目录:filesDir、cacheDir、databaseDir 等。
openSync打开/创建文件,OpenMode控制模式。writeSync/readSync读写文件。listFileSync遍历目录,statSync获取文件信息。mkdirSync/rmdirSync管理目录。unlinkSync删除文件,copyFileSync复制文件。- 文件操作后必须关闭,大文件使用异步 API。
文件管理是应用数据能力的基石,掌握它能构建文件浏览、缓存管理、数据导出等功能。下一篇我们将讲解 HarmonyOS 传感器开发。
更多推荐




所有评论(0)