Expo FileSystem readAsStringAsync报错:文件不可读问题求助
解决Expo FileSystem读取本地文件“file is not readable”问题
核心问题原因
Expo的FileSystem无法直接访问项目源码目录下的文件(比如你项目里的backend/database.json),因为这些文件在打包后不会被放到设备的可读写文件系统路径中,而是作为打包资源存在,需要通过Expo的Asset模块来加载。
具体解决步骤
1. 调整文件位置并配置metro
- 将
database.json移动到项目的assets目录下(没有的话直接新建一个) - 在
metro.config.js中添加对json文件的资源支持:const { getDefaultConfig } = require('expo/metro-config'); const config = getDefaultConfig(__dirname); config.resolver.assetExts.push('json'); module.exports = config;
2. 使用Asset模块加载并读写文件
替换原来直接读取相对路径的代码,改用Asset加载资源后,将文件副本写入设备可读写目录再操作:
import { Asset } from 'expo-asset'; import * as FileSystem from 'expo-file-system'; async function addUserCredentials(newUser) { // 加载asset中的原始json文件 const asset = Asset.fromModule(require('../assets/database.json')); await asset.downloadAsync(); // 读取下载后的asset内容,初始化用户数据 let existingData = []; try { const fileContent = await FileSystem.readAsStringAsync(asset.localUri); existingData = JSON.parse(fileContent); } catch (e) { console.log('首次使用,初始化空用户列表'); } // 将新用户数据写入设备可读写目录的文件副本 existingData.push(newUser); await FileSystem.writeAsStringAsync( `${FileSystem.documentDirectory}database.json`, JSON.stringify(existingData) ); }
3. 关键注意点
- 打包后的asset文件是只读的,必须将内容写入
FileSystem.documentDirectory(设备可读写目录)后再做修改操作 - Expo访问
documentDirectory不需要额外申请文件权限,iOS和Android都默认支持 - 后续读写用户数据时,直接操作
FileSystem.documentDirectory下的database.json即可
更优替代方案:用专用存储API存用户数据
如果只是存储账号密码这类数据,没必要用json文件,Expo提供的AsyncStorage(普通数据)或expo-secure-store(敏感数据)更简洁:
import AsyncStorage from '@react-native-async-storage/async-storage'; // 存密码这类敏感信息推荐用:import * as SecureStore from 'expo-secure-store'; async function addUserCredentials(newUser) { try { const existingUsers = await AsyncStorage.getItem('userCredentials'); const usersArray = existingUsers ? JSON.parse(existingUsers) : []; usersArray.push(newUser); await AsyncStorage.setItem('userCredentials', JSON.stringify(usersArray)); } catch (e) { console.error('存储用户数据失败:', e); } }
内容的提问来源于stack exchange,提问作者user20074138
相关产品推荐
相关产品推荐

