React Native Expo内部存储:如何先创建指定文件夹再存储JSON文件?
解决Expo中通过StorageAccessFramework先创建文件夹再保存文件的问题
你的问题出在直接通过路径拼接尝试在未创建的文件夹下创建文件——Expo的StorageAccessFramework不支持这种操作,必须先显式创建目标文件夹,再在该文件夹内创建文件。
修改后的完整代码如下:
import * as FileSystem from 'expo-file-system'; import * as Sharing from 'expo-sharing'; import { Platform } from 'react-native'; const saveJSONToFile = async (fileName, jsonData, mimetype) => { const directory = FileSystem.documentDirectory + 'my-project/'; const fileUri = directory + fileName + '.json'; try { await FileSystem.makeDirectoryAsync(directory, { intermediates: true }); await FileSystem.writeAsStringAsync(fileUri, JSON.stringify(jsonData)); console.log('临时文件URI:', fileUri); } catch (error) { console.error('保存JSON到临时文件失败:', error); } await saveFile(fileUri, fileName, mimetype); }; const saveFile = async (uri, filename, mimetype) => { if (Platform.OS === "android") { const permissions = await FileSystem.StorageAccessFramework.requestDirectoryPermissionsAsync(); if (permissions.granted) { let projectFolderUri; try { // 先创建ProjectName文件夹 projectFolderUri = await FileSystem.StorageAccessFramework.createDirectoryAsync( permissions.directoryUri, 'ProjectName', { intermediates: true } ); } catch (error) { // 如果文件夹已存在,直接复用其URI if (error.message.includes('already exists')) { projectFolderUri = `${permissions.directoryUri}/ProjectName/`; } else { console.error('创建ProjectName文件夹失败:', error); return; } } try { const base64 = await FileSystem.readAsStringAsync(uri, { encoding: FileSystem.EncodingType.Base64 }); // 在已创建的文件夹内创建目标文件 const targetFileUri = await FileSystem.StorageAccessFramework.createFileAsync( projectFolderUri, filename, mimetype ); await FileSystem.writeAsStringAsync(targetFileUri, base64, { encoding: FileSystem.EncodingType.Base64 }); console.log('文件已保存到:', targetFileUri); } catch (e) { console.error('保存文件失败:', e); } } else { await Sharing.shareAsync(uri); } } else { await Sharing.shareAsync(uri); } };
关键修改说明:
- 文件夹创建逻辑:使用
createDirectoryAsync在用户选择的目录下显式创建ProjectName文件夹,同时捕获"文件夹已存在"的错误,避免重复创建导致报错。 - 文件保存逻辑:不再直接拼接路径,而是使用已创建的文件夹URI作为父目录调用
createFileAsync,确保文件存入指定文件夹。 - 拆分原有的Promise链式调用为async/await写法,提升代码可读性和错误处理的灵活性。
内容的提问来源于stack exchange,提问作者Joseph
相关产品推荐
相关产品推荐

