uni.getFileSystemManager在App端不可用,必须改用plus.io.requestFileSystem,并配置Android/iOS权限、区分PRIVATE_DOC与PUBLIC_DOCUMENTS路径、监听onwriteend/onloadend事件。

uni-app 的 uni.getFileSystemManager 在 App 端根本不可用,调用即空对象或静默失败——这不是你代码写错了,是平台能力缺失。必须切到 plus.io 体系,且权限、路径、事件监听三者缺一不可。
App端为什么uni.getFileSystemManager返回空对象
这是 uni-app 编译为原生 App(Android/iOS)时的明确限制:uni.getFileSystemManager 仅在 H5 和小程序环境有效;App 端 runtime 不提供该 API 的实现,返回的是空对象而非报错,导致 writeFile、readFile 直接不执行或无响应。
常见错误现象包括:
- 调用
fs.writeFile后控制台无日志、文件没生成、也不进fail回调 -
console.log(fs)打印出来是{}或undefined - H5 能跑,App 打包后功能消失,且无明显报错提示
正确做法是:App 端统一使用 plus.io.requestFileSystem,它才是 HTML5+ Runtime 提供的底层文件系统入口。
App端读写文件前必须配齐的三项配置
漏配任意一项,plus.io.requestFileSystem 都会直接 fail,错误信息通常是 Permission denied 或 Operation not permitted,但不会告诉你具体缺哪个权限。
需要检查:
-
Android:在
manifest.json → 模块权限配置 → 存储权限中勾选“外部存储”(对应android.permission.WRITE_EXTERNAL_STORAGE);Android 10+ 还需开启requestLegacyExternalStorage(在android/app/build.gradle的defaultConfig中添加android:requestLegacyExternalStorage="true") -
iOS:在
manifest.json → iOS 模块配置 → NSPhotoLibraryUsageDescription填一个非空字符串(哪怕你只读写Documents/目录,iOS 也会卡在这一步) -
路径常量选择:不能手拼路径,必须用
plus.io.PRIVATE_DOC(私有目录,卸载即清)或plus.io.PUBLIC_DOCUMENTS(用户可见,适合导出文件),二者权限要求不同,别混用
读取文件时为什么拿到undefined或空内容
因为 plus.io.FileReader 是异步的,且没有 Promise 封装,必须手动监听 onloadend 事件才能拿到真实内容;在事件外直接 return 或 console.log,拿到的必然是 undefined。
典型错误写法:
fileReader.readAsText(file, "utf-8"); console.log(fileReader.result); // ❌ 此时 result 还没赋值,输出 undefined
正确写法要点:
- 必须设置
fileReader.onloadend = function(res) { ... },并在里面处理res.target.result - 不要依赖
fileReader.result属性,它只在事件触发后才有效 - 若读取 JSON,建议加 try/catch 解析,避免格式错误导致后续逻辑中断
- 路径要用
plus.io.convertLocalFileSystemURL(fileEntry.fullPath)转成可访问 URL,别直接拼"file://..." + fullPath
写入文件后文件实际没保存成功?
和读取同理:fileWriter.write() 只是把数据送进写队列,不等于落盘;必须监听 onwriteend 才能确认完成。漏掉这个事件,函数可能已退出,而文件还卡在缓冲区里。
关键点:
-
fileWriter.onwriteend是唯一可靠的完成信号,onwrite只表示某次写操作完成(分片写时会多次触发) - 写入前建议先
fileEntry.createWriter(),不要复用旧的 writer 实例 - 写 JSON 时用
fileWriter.write(JSON.stringify(data))没问题,但别忘了fileWriter.onerror捕获编码或磁盘满等异常 - 如果要追加内容,得先
fileEntry.file()读取原文件,再createWriter()写入合并后的内容——plus.io没有原生append方法
最易被忽略的是:iOS 上即使你只操作 Documents/,也强制要求声明 NSPhotoLibraryUsageDescription;而 Android 11+ 若未适配分区存储,PUBLIC_DOCUMENTS 可能写入失败却无明确提示——这些都不是代码逻辑问题,而是平台策略细节,必须前置验证。


















