在 HarmonyOS 应用中,文件操作几乎是刚需:用户文档、缓存图片、下载的 PDF、录音文件……如果不清楚沙箱边界、目录结构和权限模型,极易踩坑:存错目录导致卸载后数据丢失、跨应用共享失败、或因权限不足崩溃。
本文聚焦 HarmonyOS 文件管理的核心场景:
HarmonyOS 应用运行在沙箱环境中,每个应用拥有独立的文件空间。Stage 模型下,常用目录包括:
import { common } from '@kit.AbilityKit';
@Entry
@Component
struct FilePathDemo {
@State cacheDir: string = '';
@State filesDir: string = '';
@State tempDir: string = '';
aboutToAppear() {
const context = getContext(this) as common.UIAbilityContext;
this.cacheDir = context.cacheDir; // /data/storage/el2/base/cache
this.filesDir = context.filesDir; // /data/storage/el2/base/files
this.tempDir = context.tempDir; // /data/storage/el2/base/temp
}
build() {
Column({ space: 12 }) {
Text(`Cache: ${this.cacheDir}`)
Text(`Files: ${this.filesDir}`)
Text(`Temp: ${this.tempDir}`)
}.padding(20)
}
}HarmonyOS 提供 @ohos.file.fs 模块进行同步/异步文件操作,API 风格类似 Node.js。
import { fileIo as fs } from '@kit.CoreFileKit';
import { common } from '@kit.AbilityKit';
async function writeTextFile(fileName: string, content: string) {
const context = getContext() as common.UIAbilityContext;
const filePath = `${context.filesDir}/${fileName}`;
try {
const file = fs.openSync(filePath, fs.OpenMode.CREATE | fs.OpenMode.WRITE_ONLY);
fs.writeSync(file.fd, content);
fs.closeSync(file.fd);
console.info(`文件已写入: ${filePath}`);
} catch (err) {
console.error(`写入失败: ${err.message}`);
}
}
// 使用
writeTextFile('user_notes.txt', '这是用户笔记内容');async function readTextFile(fileName: string): Promise {
const context = getContext() as common.UIAbilityContext;
const filePath = `${context.filesDir}/${fileName}`;
try {
const file = fs.openSync(filePath, fs.OpenMode.READ_ONLY);
const stat = fs.statSync(filePath);
const buffer = new ArrayBuffer(stat.size);
fs.readSync(file.fd, buffer);
fs.closeSync(file.fd);
const decoder = new util.TextDecoder('utf-8');
return decoder.decodeWithStream(new Uint8Array(buffer));
} catch (err) {
console.error(`读取失败: ${err.message}`);
return '';
}
}// 复制文件
fs.copyFileSync(srcPath, destPath);
// 删除文件
fs.unlinkSync(filePath);
// 检查文件是否存在
const exists = fs.accessSync(filePath);若需访问用户的照片、文档、下载文件等公共目录,必须通过 Picker(文件选择器)或申请 ohos.permission.READ_MEDIA 等权限。
import { picker } from '@kit.CoreFileKit';
async function pickDocument(): Promise {
try {
const documentPicker = new picker.DocumentViewPicker();
const result = await documentPicker.select({
maxSelectNumber: 1
});
if (result && result.length > 0) {
const uri = result[0];
console.info(`选中文件 URI: ${uri}`);
return uri;
}
} catch (err) {
console.error(`选择文件失败: ${err.message}`);
}
return '';
}若需批量访问或后台访问用户文件,需在 module.json5 中声明权限:
{
"requestPermissions": [
{
"name": "ohos.permission.READ_MEDIA",
"reason": "$string:media_read_reason",
"usedScene": {
"abilities": ["EntryAbility"],
"when": "inuse"
}
}
]
}运行时动态申请:
import { abilityAccessCtrl, common } from '@kit.AbilityKit';
async function requestMediaPermission() {
const context = getContext() as common.UIAbilityContext;
const atManager = abilityAccessCtrl.createAtManager();
try {
const result = await atManager.requestPermissionsFromUser(context, ['ohos.permission.READ_MEDIA']);
if (result.authResults[0] === 0) {
console.info('媒体读取权限已授予');
return true;
}
} catch (err) {
console.error(`权限申请失败: ${err.message}`);
}
return false;
}HarmonyOS 支持分布式文件能力,允许应用在多设备间共享文件(如手机 ↔ 平板、PC)。核心 API 位于 @ohos.file.distributedFile。
import { distributedFile } from '@kit.CoreFileKit';
async function enableDistributedFile(deviceId: string, fileName: string) {
try {
const remotePath = `${deviceId}/data/storage/el2/base/files/${fileName}`;
const localPath = `/data/storage/el2/distributedfiles/${fileName}`;
await distributedFile.access(remotePath);
console.info(`远程文件可访问: ${remotePath}`);
// 后续可通过 fs 模块读取 localPath(系统自动同步)
} catch (err) {
console.error(`分布式文件访问失败: ${err.message}`);
}
}将常用操作封装为工具类,简化调用:
import { fileIo as fs } from '@kit.CoreFileKit';
import { common } from '@kit.AbilityKit';
export class FileManager {
private static context: common.UIAbilityContext;
static init(ctx: common.UIAbilityContext) {
this.context = ctx;
}
// 写入文本到 files 目录
static async writeText(fileName: string, content: string): Promise {
const filePath = `${this.context.filesDir}/${fileName}`;
try {
const file = fs.openSync(filePath, fs.OpenMode.CREATE | fs.OpenMode.WRITE_ONLY);
fs.writeSync(file.fd, content);
fs.closeSync(file.fd);
return true;
} catch (err) {
console.error(`FileManager.writeText 失败: ${err.message}`);
return false;
}
}
// 读取文本
static async readText(fileName: string): Promise {
const filePath = `${this.context.filesDir}/${fileName}`;
try {
const file = fs.openSync(filePath, fs.OpenMode.READ_ONLY);
const stat = fs.statSync(filePath);
const buffer = new ArrayBuffer(stat.size);
fs.readSync(file.fd, buffer);
fs.closeSync(file.fd);
const decoder = new util.TextDecoder('utf-8');
return decoder.decodeWithStream(new Uint8Array(buffer));
} catch (err) {
console.error(`FileManager.readText 失败: ${err.message}`);
return '';
}
}
// 删除文件
static delete(fileName: string): boolean {
const filePath = `${this.context.filesDir}/${fileName}`;
try {
fs.unlinkSync(filePath);
return true;
} catch (err) {
console.error(`FileManager.delete 失败: ${err.message}`);
return false;
}
}
// 检查文件是否存在
static exists(fileName: string): boolean {
const filePath = `${this.context.filesDir}/${fileName}`;
try {
return fs.accessSync(filePath);
} catch {
return false;
}
}
// 清空 cache 目录
static clearCache(): boolean {
try {
const cacheDir = this.context.cacheDir;
const files = fs.listFileSync(cacheDir);
files.forEach(file => {
fs.unlinkSync(`${cacheDir}/${file}`);
});
return true;
} catch (err) {
console.error(`FileManager.clearCache 失败: ${err.message}`);
return false;
}
}
}// 初始化
FileManager.init(getContext(this) as common.UIAbilityContext);
// 写入文件
await FileManager.writeText('config.json', JSON.stringify({ theme: 'dark' }));
// 读取文件
const configText = await FileManager.readText('config.json');
const config = JSON.parse(configText);
// 检查文件
if (FileManager.exists('user_data.txt')) {
console.info('用户数据文件存在');
}
// 清空缓存
FileManager.clearCache();坑点 | 表现 | 解决方案 |
|---|---|---|
文件存到 cache 目录后找不到 | 系统清理缓存后文件丢失 | 重要数据存 files/,缓存仅用于可再生内容 |
跨应用共享文件失败 | 无法通过文件路径直接访问 | 使用 Picker 或 ContentProvider 共享 URI |
文件路径包含中文导致读取失败 | 编码问题 | 使用 UTF-8 编码,避免特殊字符 |
分布式文件同步延迟高 | 大文件同步慢 | 分块传输、压缩、或使用云存储中转 |
权限申请后仍无法访问 | 权限声明不完整 | 检查 module.json5 和运行时申请是否都完成 |
HarmonyOS 文件管理的核心是理解沙箱边界与权限模型:
封装统一的 FileManager 工具类,可显著降低文件操作的复杂度,提升代码可维护性。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。