Skip to content

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 foundreadFile 文件不存在
file too largereadFile 超 16 MB
read failed / write failed / mkdir failed / remove failedIO 错误
invalid base64writeFile 入参非合法 base64
not a dirlistDir 目标非目录
dir not emptyremove 非空目录

实现细节

  • namespace webview::detail::fsxfs.hpp),fsx 避与 std::filesystem 冲突
  • safe_path::resolveAndCheckweakly_canonical + lexically_normal + 逐段前缀比较
  • userData 线程安全(static 局部单例 + create_directories 幂等)
  • std::error_code 无异常抛出

下一步