Expo环境下React Native读取文件及react-native-fs失效问题解决
问题根因
react-native-fs无法在Expo托管工作流下直接运行:该库依赖自定义原生模块链接,Expo默认托管环境未内置该库的原生编译产物,原生模块未注册就会抛出null is not an object (evaluating RNFSManager.RNFSFileTypeRegular)错误,重装依赖、清缓存都无法解决,不弹出Expo的前提下不需要再尝试这个方案。FileSystem.readAsStringAsync返回{"_U":0, "_V":0, "_W": null, "_X": null}是未正确等待Promise执行完成的典型表现:这个结构是JS环境中未resolved的Promise对象的内部属性,说明调用时没有加await或没有通过.then()接收结果,不是方法本身失效。
无第三方原生依赖的实现方案
直接使用Expo官方维护的expo-document-picker+expo-file-system组合即可,两个库均为Expo SDK内置支持,不需要额外原生链接、不需要单独申请存储权限。
- 正确导入依赖
import * as DocumentPicker from 'expo-document-picker'; import * as FileSystem from 'expo-file-system';
- 完整选文件、读内容逻辑
const pickAndReadLocalText = async () => { try { // 拉起系统文件选择器 const pickRes = await DocumentPicker.getDocumentAsync({ type: 'text/plain', // 按需调整MIME类型,比如要读csv就加'text/csv' copyToCacheDirectory: true, // 必选参数:将选中文件拷贝到应用沙箱缓存目录,解决安卓高版本权限问题 }); // 用户主动取消选择时直接返回 if (pickRes.canceled) return; // 取文件访问URI,注意expo-document-picker v12+版本返回结构为assets数组,旧版本直接取pickRes.uri即可 const targetFileUri = pickRes.assets[0].uri; // 以UTF8编码读取文本内容 const textContent = await FileSystem.readAsStringAsync(targetFileUri, { encoding: FileSystem.EncodingType.UTF8, }); // textContent就是最终读到的文件文本内容,可直接用于后续业务逻辑 console.log('读取到的文件内容:', textContent); return textContent; } catch (err) { console.error('读取失败:', err); alert('文件读取失败,请确认文件为未损坏的文本格式'); } };
避坑提示
- 必须开启
copyToCacheDirectory: true:安卓13及以上版本对公共存储目录权限管控严格,应用没有权限直接读取用户选中文件的原始路径,只有拷贝到应用自身沙箱目录后才能正常访问。 - 所有异步方法必须加
await,或在.then()回调中接收结果,直接打印未完成的Promise对象就会出现你看到的_U/_V/_W/_X结构。 - 不需要额外申请存储权限:系统文件选择器走的是系统级临时授权流程,拷贝到缓存目录后的读取操作完全在应用沙箱内完成,不需要额外申请读写存储的敏感权限。
- 如果读取中文文件出现乱码,可根据文件实际编码调整encoding参数,比如GBK编码的文件可以先读成base64再用转码库处理。
内容的提问来源于stack exchange,提问作者Fosowl
相关产品推荐
相关产品推荐

