Path / fs API
WindowTem::bindPublicSlots() 自动绑的 7 个内置槽(getPath + 6 fs.*)。前端经 bridge.call 调用,无需手绑。
槽归
bindPublicSlots(基础设施),子类initBridge只绑业务槽,name 不冲突。见 WindowTem 模板。
getPath
js
const p = await bridge.call('getPath', name)name | 返回 |
|---|---|
'userData' | %APPDATA%\<exe 名>(首调自动建) |
'appData' | %APPDATA% |
'home' | %USERPROFILE% |
'temp' | %TEMP%\ |
'exe' | exe 绝对路径 |
| 其他 | null |
C++ 端无 IO,秒返。前端 bridge.call 统一 Promise,需 await。
fs.readFile
js
const r = await bridge.call('fs.readFile', path)
// r: { content: <base64>, size: <bytes> } | { error: '...' }path:相对 userData(推荐)或绝对(须在 userData 子树内)content:base64 编码(atob解码)- 上限 16 MB,超
{error:"file too large"} - 不存在
{error:"not found"} - 越界
{error:"out of userData"}
fs.writeFile
js
await bridge.call('fs.writeFile', path, base64Content)
// { ok: true } | { error: '...' }- 入参 base64(
btoa编码) - 自动建父目录(recursive)
- truncate 模式(不支持 append)
- base64 非法
{error:"invalid base64"}
fs.exists
js
await bridge.call('fs.exists', path) // { exists: bool }- 越界返
{exists:false}(不泄露)
fs.mkdir
js
await bridge.call('fs.mkdir', path) // { ok: true } | { error: '...' }- recursive(自动建父目录)
- 幂等(已存在
{ok:true})
fs.listDir
js
await bridge.call('fs.listDir', path)
// { entries: [{ name, isDir, size }] } | { error: 'not a dir' }- 非目录
{error:"not a dir"} size:目录为 0,文件为字节数
fs.remove
js
await bridge.call('fs.remove', path) // { ok: true } | { error: '...' }- 仅删文件或空目录(非空
{error:"dir not empty"}) - 幂等(不存在
{ok:true})
错误码汇总
| error | 触发 |
|---|---|
out of userData | 路径越界 userData 子树 |
not found | readFile 文件不存在 |
file too large | readFile 超 16 MB |
read failed / write failed / mkdir failed / remove failed | IO 错误 |
invalid base64 | writeFile 入参非合法 base64 |
not a dir | listDir 目标非目录 |
dir not empty | remove 非空目录 |
实现细节
- namespace
webview::detail::fsx(fs.hpp),fsx避与std::filesystem冲突 safe_path::resolveAndCheck:weakly_canonical+lexically_normal+ 逐段前缀比较- userData 线程安全(static 局部单例 +
create_directories幂等) - 全
std::error_code无异常抛出