@cordova-ohos/cordova-plugin-file
v8.1.3
Published
Cordova file Plugin
Readme
cordova-plugin-file
一款 Cordova 插件,提供完善的文件 API,支持对设备本地文件系统中的文件和目录进行读写操作。该插件遵循 W3C 文件 API 规范,并提供平台特定扩展以适配不同系统的文件系统特性,本文档主要说明该插件在HarmonyOS系统中的应用。
安装
#安装hcordova
npm install -g hcordova通过 hcordova 安装(推荐)
#全平台安装
hcordova plugin add cordova-plugin-file
#指定鸿蒙平台安装
hcordova plugin add cordova-plugin-file --platform ohos通过 Git 安装
直接从 GitCode 仓库安装最新开发版本:
hcordova plugin add https://gitcode.com/OpenHarmony-Cordova/cordova-plugin-file.git --platform ohos卸载
#全平台卸载
hcordova plugin remove cordova-plugin-file
#指定OHOS平台卸载
hcordova plugin remove cordova-plugin-file --platform ohos文件系统结构
不同平台拥有独特的文件系统结构。该插件通过 cordova.file 对象提供标准化 URL,用于跨平台访问常用目录。
cordova.file 对象参考
| Cordova 目录常量 | 鸿蒙目录路径 |
| -------------------------------------------------- | ------------------------------ |
| cordova.file.applicationDirectory | /data/storage/el2 |
| cordova.file.applicationStorageDirectory | /data/storage/el2/base/files |
| cordova.file.dataDirectory | /data/storage/el2/base/files |
| cordova.file.cacheDirectory | /data/storage/el2/base/cache |
| cordova.file.externalApplicationStorageDirectory | /data/storage/el2/base/files |
| cordova.file.externalDataDirectory | /data/storage/el2/base/files |
| cordova.file.externalRootDirectory | /data/storage/el2 |
| cordova.file.tempDirectory | /data/storage/el2/base/temp |
| cordova.file.syncedDataDirectory | /data/storage/el2/base/files |
| cordova.file.documentsDirectory | /data/storage/el2/base/files |
| cordova.file.sharedDirectory | /data/storage/el2/base/files |
| Cordova 目录常量 |常量值 | 鸿蒙内部目录路径 |
| --------------------------|--| ------------------------------ |
| LocalFileSystem.TEMPORARY| 0 | /data/storage/el2/base/temp |
| LocalFileSystem.PERSISTENT| 1 | /data/storage/el2/base/files |
核心概念
关键实体
FileSystem:表示已挂载的文件系统(如持久化存储或临时存储)DirectoryEntry:表示文件系统中的目录(提供文件 / 目录操作方法)FileEntry:表示文件系统中的文件(提供文件内容读写方法)File:包含文件元数据(大小、类型、最后修改时间)和原始内容FileWriter:向FileEntry写入内容(支持追加、截断和定位操作)FileReader:从File读取内容(支持文本、二进制和数据 URL 格式)
文件系统类型
LocalFileSystem.PERSISTENT:持久化存储(应用重启 / 更新后数据保留;部分平台需用户授权)LocalFileSystem.TEMPORARY:临时存储(系统空间不足时可能清理;无需授权)
API 说明
1. 文件系统初始化
window.requestFileSystem(type, size, successCallback, errorCallback)
请求访问指定类型和大小的文件系统。
| 参数 | 类型 | 描述 |
| ----------------- | -- | ---------------------------------------------------------- |
| type | 数字 | LocalFileSystem.PERSISTENT 或 LocalFileSystem.TEMPORARY |
| size | 数字 | 配额大小(单位:字节) ,通常情况此参数忽略,默认传0 |
| successCallback | 函数 | 成功时调用,参数为 FileSystem 对象 |
| errorCallback | 函数 | 失败时调用,参数为 FileError 对象 |
示例:
// 请求持久化存储
window.requestFileSystem(
LocalFileSystem.PERSISTENT,
0,
(fs) => {
console.log(`文件系统已打开:${fs.name}(根目录:${fs.root.fullPath})`);
// 使用 fs.root(DirectoryEntry 对象)进行后续操作
},
(error) => {
console.error(`打开文件系统失败:${getErrorMessage(error)}`);
}
);window.resolveLocalFileSystemURL(url, successCallback, errorCallback)
将本地文件系统 URL(如 cordova.file 常量中的 URL)解析为 DirectoryEntry 或 FileEntry 对象。
| 参数 | 类型 | 描述 |
| ----------------- | --- | ------------------------------------------- |
| url | 字符串 | 本地文件系统 URL(例如 cordova.file.dataDirectory) |
| successCallback | 函数 | 成功时调用,参数为 DirectoryEntry 或 FileEntry 对象 |
| errorCallback | 函数 | 失败时调用,参数为 FileError 对象 |
示例:
// 将数据目录 URL 解析为 DirectoryEntry 对象
window.resolveLocalFileSystemURL(
cordova.file.dataDirectory,
(dirEntry) => {
console.log(`已解析目录:${dirEntry.name}(路径:${dirEntry.fullPath})`);
},
(error) => {
console.error(`解析 URL 失败:${getErrorMessage(error)}`);
}
);2. 目录操作
所有目录操作均通过 DirectoryEntry 对象的方法实现。
创建目录
dirEntry.getDirectory(name, options, successCallback, errorCallback)
| 参数 | 类型 | 描述 |
| --------- | --- | -------------------------------------------------------------------- |
| name | 字符串 | 要创建 / 获取的目录名称 |
| options | 对象 | { create: 布尔值, exclusive: 布尔值 }(create:不存在时是否创建;exclusive:存在时是否报错) |
示例:
function createAppDirectory(directoryName) {
window.resolveLocalFileSystemURL(
cordova.file.dataDirectory,
(rootDir) => {
// 目录不存在时创建
rootDir.getDirectory(
directoryName,
{ create: true, exclusive: false },
(newDir) => {
console.log(`目录已创建:${newDir.fullPath}`);
},
(error) => console.error(`创建目录失败:${getErrorMessage(error)}`)
);
},
(error) => console.error(`解析根目录失败:${getErrorMessage(error)}`)
);
}
// 使用:在数据目录中创建 "app_data" 目录
createAppDirectory("app_data");列出目录内容
dirEntry.createReader() → DirectoryReader.readEntries(successCallback, errorCallback)
示例:
function listDirectoryContents(directoryURL) {
window.resolveLocalFileSystemURL(
directoryURL,
(dirEntry) => {
const dirReader = dirEntry.createReader();
dirReader.readEntries(
(entries) => {
if (entries.length === 0) {
console.log("目录为空");
return;
}
entries.forEach((entry) => {
const entryType = entry.isFile ? "文件" : "目录";
console.log(`${entry.name}(${entryType})- 路径:${entry.fullPath}`);
});
},
(error) => console.error(`读取目录失败:${getErrorMessage(error)}`)
);
},
(error) => console.error(`解析目录失败:${getErrorMessage(error)}`)
);
}
// 使用:列出数据目录的内容
listDirectoryContents(cordova.file.dataDirectory);删除目录
dirEntry.remove(successCallback, errorCallback)
示例:
function deleteEmptyDirectory(directoryName) {
window.resolveLocalFileSystemURL(
cordova.file.dataDirectory + directoryName,
(dirEntry) => {
dirEntry.remove(
() => console.log(`目录已删除:${directoryName}`),
(error) => console.error(`删除目录失败:${getErrorMessage(error)}`)
);
},
(error) => console.error(`目录不存在:${getErrorMessage(error)}`)
);
}
// 使用:删除 "old_data" 目录(必须为空)
deleteEmptyDirectory("old_data");3. 文件操作
所有文件操作均通过 FileEntry 对象的方法实现。
创建文件
dirEntry.getFile(name, options, successCallback, errorCallback)
| 参数 | 类型 | 描述 |
| --------- | --- | ---------------------------------------------- |
| name | 字符串 | 要创建 / 获取的文件名称 |
| options | 对象 | { create: 布尔值, exclusive: 布尔值 }(与目录操作参数含义相同) |
示例:
function createNewFile(fileName) {
window.resolveLocalFileSystemURL(
cordova.file.dataDirectory,
(rootDir) => {
rootDir.getFile(
fileName,
{ create: true, exclusive: false },
(fileEntry) => {
console.log(`文件已创建:${fileEntry.name}(路径:${fileEntry.fullPath})`);
},
(error) => console.error(`创建文件失败:${getErrorMessage(error)}`)
);
},
(error) => console.error(`解析根目录失败:${getErrorMessage(error)}`)
);
}
// 使用:在数据目录中创建 "user_settings.txt" 文件
createNewFile("user_settings.txt");写入文件
fileEntry.createWriter(successCallback, errorCallback) → FileWriter.write(blob)
示例(文本内容):
function writeTextToFile(fileName, content) {
window.resolveLocalFileSystemURL(
cordova.file.dataDirectory,
(rootDir) => {
rootDir.getFile(
fileName,
{ create: true, exclusive: false },
(fileEntry) => {
fileEntry.createWriter(
(fileWriter) => {
// 写入完成回调
fileWriter.onwriteend = () => {
console.log(`成功写入文件:${fileName}`);
};
// 写入错误回调
fileWriter.onerror = (error) => {
console.error(`写入失败:${getErrorMessage(error)}`);
};
// 将文本转换为 Blob(支持 UTF-8 编码)
const textBlob = new Blob([content], { type: "text/plain;charset=utf-8" });
fileWriter.write(textBlob);
},
(error) => console.error(`创建写入器失败:${getErrorMessage(error)}`)
);
},
(error) => console.error(`获取文件失败:${getErrorMessage(error)}`)
);
},
(error) => console.error(`解析根目录失败:${getErrorMessage(error)}`)
);
}
// 使用:将用户偏好设置写入 "user_settings.txt"
const userSettings = JSON.stringify({ theme: "dark", notifications: true });
writeTextToFile("user_settings.txt", userSettings);示例(二进制内容 - 如图片):
async function writeBinaryToFile(fileName, binaryData) {
try {
const rootDir = await new Promise((resolve, reject) => {
window.resolveLocalFileSystemURL(cordova.file.dataDirectory, resolve, reject);
});
const fileEntry = await new Promise((resolve, reject) => {
rootDir.getFile(fileName, { create: true, exclusive: false }, resolve, reject);
});
const fileWriter = await new Promise((resolve, reject) => {
fileEntry.createWriter(resolve, reject);
});
fileWriter.onwriteend = () => {
console.log(`二进制数据已写入:${fileName}`);
};
fileWriter.onerror = (error) => {
throw new Error(`二进制写入失败:${getErrorMessage(error)}`);
};
// 假设 binaryData 是 ArrayBuffer 或 Uint8Array 类型
const binaryBlob = new Blob([binaryData], { type: "application/octet-stream" });
fileWriter.write(binaryBlob);
} catch (error) {
console.error(`二进制文件操作失败:${error.message}`);
}
}
// 使用:将图片(ArrayBuffer 类型)写入 "profile_pic.png"
// fetchImageAsArrayBuffer().then(buffer => writeBinaryToFile("profile_pic.png", buffer));读取文件
fileEntry.file(successCallback, errorCallback) → FileReader.readAs*()
支持的读取格式:
readAsText(file):以 UTF-8 文本格式读取readAsDataURL(file):以 base64 编码的 data URL 格式读取(适用于图片)readAsArrayBuffer(file):以二进制 ArrayBuffer 格式读取readAsBinaryString(file):以原始二进制字符串格式读取(已废弃)
示例(读取文本):
function readTextFromFile(fileName) {
window.resolveLocalFileSystemURL(
cordova.file.dataDirectory + fileName,
(fileEntry) => {
fileEntry.file(
(file) => {
const fileReader = new FileReader();
fileReader.onloadend = () => {
const fileContent = fileReader.result;
console.log(`文件内容(${fileName}):`, fileContent);
// 处理内容(如解析 JSON)
try {
const parsedData = JSON.parse(fileContent);
console.log("解析后的 JSON 数据:", parsedData);
} catch (e) {
console.log("内容非 JSON 格式:", fileContent);
}
};
fileReader.onerror = (error) => {
console.error(`读取失败:${getErrorMessage(error)}`);
};
// 以文本格式读取文件
fileReader.readAsText(file);
},
(error) => console.error(`访问文件失败:${getErrorMessage(error)}`)
);
},
(error) => console.error(`文件不存在:${getErrorMessage(error)}`)
);
}
// 使用:读取 "user_settings.txt" 文件
readTextFromFile("user_settings.txt");删除文件
fileEntry.remove(successCallback, errorCallback)
示例:
function deleteFile(fileName) {
window.resolveLocalFileSystemURL(
cordova.file.dataDirectory + fileName,
(fileEntry) => {
fileEntry.remove(
() => console.log(`文件已删除:${fileName}`),
(error) => console.error(`删除文件失败:${getErrorMessage(error)}`)
);
},
(error) => console.error(`文件不存在:${getErrorMessage(error)}`)
);
}
// 使用:删除 "old_logs.txt" 文件
deleteFile("old_logs.txt");4. 错误处理
所有 API 方法失败时都会返回 FileError 对象,可通过 code 属性识别错误类型。
FileError 错误码参考
| 错误码常量 | 值 | 描述 |
| --------------------------------------- | -- | -------------------------- |
| FileError.NOT_FOUND_ERR | 1 | 文件或目录不存在 |
| FileError.SECURITY_ERR | 2 | 安全限制(如权限不足) |
| FileError.ABORT_ERR | 3 | 操作被用户或系统中止 |
| FileError.NOT_READABLE_ERR | 4 | 文件或目录不可读 |
| FileError.ENCODING_ERR | 5 | 编码错误(如 URL 格式无效) |
| FileError.NO_MODIFICATION_ALLOWED_ERR | 6 | 不允许修改(如只读目录) |
| FileError.INVALID_STATE_ERR | 7 | 状态无效(如向已关闭的 FileWriter 写入) |
| FileError.SYNTAX_ERR | 8 | 语法错误(如文件名无效) |
| FileError.INVALID_MODIFICATION_ERR | 9 | 修改无效(如跨文件系统移动目录) |
| FileError.QUOTA_EXCEEDED_ERR | 10 | 存储配额超出 |
错误信息辅助函数
function getErrorMessage(error) {
const errorMessages = {
1: "文件或目录不存在",
2: "安全错误(权限不足)",
3: "操作已中止",
4: "文件/目录不可读",
5: "编码错误(URL 无效)",
6: "不允许修改(只读)",
7: "状态无效(如写入器已关闭)",
8: "语法错误(文件名无效)",
9: "修改无效(跨文件系统)",
10: "存储配额超出"
};
return errorMessages[error.code] || `未知错误(错误码:${error.code})`;
}使用示例
示例 1:保存和加载用户偏好设置
// 将偏好设置保存到 JSON 文件
function savePreferences(preferences) {
const jsonContent = JSON.stringify(preferences, null, 2);
writeTextToFile("preferences.json", jsonContent);
}
// 从 JSON 文件加载偏好设置
function loadPreferences(onSuccess) {
readTextFromFile("preferences.json", (content) => {
try {
const preferences = JSON.parse(content);
onSuccess(preferences);
} catch (e) {
console.error("解析偏好设置失败:", e);
onSuccess(null); // 解析失败时返回 null
}
});
}
// 使用
const userPrefs = { theme: "light", notifications: true, language: "en" };
savePreferences(userPrefs);
loadPreferences((loadedPrefs) => {
if (loadedPrefs) {
console.log("加载的偏好设置:", loadedPrefs);
} else {
console.log("使用默认偏好设置");
}
});示例 2:从 URL 下载并保存文件
function downloadFile(url, destinationFileName) {
// 显示加载指示器(可选)
console.log(`正在下载 ${url}...`);
fetch(url)
.then((response) => {
if (!response.ok) {
throw new Error(`HTTP 错误!状态码:${response.status}`);
}
return response.blob(); // 以 Blob 格式获取文件
})
.then((blob) => {
window.resolveLocalFileSystemURL(
cordova.file.dataDirectory,
(rootDir) => {
rootDir.getFile(
destinationFileName,
{ create: true, exclusive: false },
(fileEntry) => {
fileEntry.createWriter(
(fileWriter) => {
fileWriter.onwriteend = () => {
console.log(`文件已下载至:${fileEntry.fullPath}`);
// 隐藏加载指示器(可选)
};
fileWriter.onerror = (error) => {
throw new Error(`写入文件失败:${getErrorMessage(error)}`);
};
fileWriter.write(blob);
},
(error) => console.error(`创建写入器失败:${getErrorMessage(error)}`)
);
},
(error) => console.error(`获取文件失败:${getErrorMessage(error)}`)
);
},
(error) => console.error(`解析目录失败:${getErrorMessage(error)}`)
);
})
.catch((error) => {
console.error(`下载失败:${error.message}`);
// 隐藏加载指示器(可选)
});
}
// 使用:下载图片并保存为 "downloaded_image.jpg"
downloadFile("https://example.com/image.jpg", "downloaded_image.jpg");平台特定说明
HarmonyOS
权限设置:
- 在鸿蒙系统中,对沙箱文件的读写,无需申请额外权限,默认具备读写权限
许可证
本插件基于 Apache 许可证 2.0 版 开源。详见 LICENSE 文件。
参考资料
Android/iOS 插件:npmjs.com
Cordova 团队对 Cordova 生态系统的维护。
所有为该插件改进做出贡献的开发者。
W3C 组织制定的 File API 规范。
