读取、预览与保存文件
使用真实桥接方法,处理大表格、返回值与写入失败。
本页目录
先理解调用与授权是两件事#
插件窗口收到的 api 来自当前宿主的 window.electronAPI。方法存在,只代表可以发起调用;主进程还会核对路径允许范围、当前窗口授权和输入原件是否只读。
路径应来自用户明确选择或当前项目已登记的材料。另一个窗口传来一个字符串,不代表当前窗口已经取得读取或写入许可。
接口速查#
| 方法 | 成功时应检查的内容 | 常见失败 |
|---|---|---|
readFileContent(path, options) |
success,再区分 text 与 table/rows |
路径不允许、文件不存在、格式不支持 |
previewFileStamp(path) |
成功状态与文件 stamp;缺失另行处理 | 文件变化、文件不存在、元数据读取失败 |
writeFileContent(path, text, options) |
success: true,可能附加其他状态 |
原件只读、路径不足、导出冲突、协作中断 |
最终返回值以目标版本的 src/ipc/file.js 和文件服务为准。不要对所有格式都假定 result.text 存在。
读取小型已知文本#
async function readKnownText(api, filePath) {
if (!api || typeof api.readFileContent !== 'function') {
throw new Error('当前宿主没有提供文本读取能力');
}
const result = await api.readFileContent(filePath);
if (!result || result.success !== true || typeof result.text !== 'string') {
throw new Error(result && result.error || '文本读取失败');
}
return result.text;
}不要拿这个函数处理任意二进制或完整巨型表格。确认格式和用途后,再决定采用文本、预览或后台分析路径。
分页读取表格预览#
async function readFirstTablePage(api, filePath) {
if (!api || typeof api.readFileContent !== 'function') {
throw new Error('当前宿主没有提供文件预览能力');
}
if (!/\.(csv|tsv|xlsx|xls)$/i.test(filePath)) {
throw new Error('请选择受支持的表格文件');
}
const result = await api.readFileContent(filePath, {
preview: true,
rowOffset: 0,
rowLimit: 60,
columnOffset: 0,
columnLimit: 12
});
if (!result || result.success !== true || result.table !== true) {
throw new Error(result && result.error || '表格预览失败');
}
return {
rows: result.rows,
hasMore: result.hasMore === true,
nextOffset: result.rowOffset + result.rows.length,
totalRows: result.totalRows ?? null
};
}当前表格预览的行数默认 60、上限 120,列数默认 16、上限 40。分页返回可能包括 paged、table、rows、rowOffset、columnOffset、hasMore 等字段。
部分文件尚未扫描到末尾时 totalRows 可以未知。依据 hasMore 决定是否请求下一页,不把未知总数当成零,不并发请求全部页面来伪装分页。
单元格用文本节点或 textContent 渲染,不能将文件原文拼进 innerHTML。当前其他格式的文本预览、二进制处理与表格预览并不是同一个契约。
保存文本并保留失败状态#
async function saveKnownText(api, filePath, content) {
if (!api || typeof api.writeFileContent !== 'function') {
throw new Error('当前宿主没有提供写入能力');
}
if (typeof content !== 'string') throw new Error('内容必须是文本');
const result = await api.writeFileContent(filePath, content);
if (!result || result.success !== true) {
throw new Error(result && result.error || '保存失败,内容仍未保存');
}
return { path: filePath, watermarked: result.watermarked === true };
}函数不会创建文件选择器,也不会授予权限。调用者应先取得允许的输出位置;失败时保留编辑内容。不要传 trusted: true 尝试取得权限,主进程信任来自当前窗口的真实选择授权。
预览刷新与外部变化#
保存当前文件的路径和 stamp。收到受支持的变化通知或用户明确刷新时重新核对;不同则提示“文件已更新,刷新查看”。不要高频读取整个大文件进行比较。
如果本地还有未保存编辑,应把外部修改视为需要处理的冲突,不能自动覆盖编辑区。
文件能力验收#
测试合法小文件、丢失文件、未授权路径、只读原件、未知总行数、大表分页、保存失败、文件外部变化和协作连接中断。成功与失败的提示都应能对应实际文件状态。