You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Expo React Native FileSystem无法在设备保存文件求助

Expo React Native FileSystem 文件保存失败 & CreateDownloadResumable 错误解决方案

一、搞定downloadAsync存不了文件的问题

你代码里踩了几个常见坑,直接导致文件存不上:

  1. 目录创建没等完成就下载
    你用.then()处理目录检查,但没等makeDirectoryAsync执行完就跑downloadAsync,这时候目录可能还没建好,下载路径直接无效。改成异步等待就行:
const downloadFile = async (url) => {
    try {
        console.log("Started");
        setLoadingModal(true)
        console.log(url);
        
        const fileName = url?.split('/').pop(); // 用pop()更简洁获取文件名
        const savePath = `${FileSystem.documentDirectory}FirstOG/`;

        // 先等目录检查+创建完成
        const { exists } = await FileSystem.getInfoAsync(savePath);
        if (!exists) {
            console.log("Creating directory...");
            // 加intermediates: true确保父目录不存在时也能创建
            await FileSystem.makeDirectoryAsync(savePath, { intermediates: true });
        }

        const downloadResult = await FileSystem.downloadAsync(
            url,
            `${savePath}${fileName}`
        );

        console.log("Download result:", downloadResult);
        console.log(`File saved to ${downloadResult.uri}`);
        
        // 先验证文件真的存在不
        const fileCheck = await FileSystem.getInfoAsync(downloadResult.uri);
        console.log("File exists post-download:", fileCheck.exists);

        // 别用Linking.openURL打开私有目录文件,用expo-file-viewer更靠谱
        // 先装依赖:npm install expo-file-viewer
        // import * as FileViewer from 'expo-file-viewer';
        // await FileViewer.open(downloadResult.uri);
    } catch (error) {
        console.error('Download error:', error);
    } finally {
        setLoadingModal(false);
    }
};
  1. 权限没配到位
  • iOS:必须在app.json里加相册写入权限描述,不然系统直接拒:
{
  "expo": {
    "ios": {
      "infoPlist": {
        "NSPhotoLibraryAddUsageDescription": "需要访问相册保存下载的文件"
      }
    }
  }
}
  • Android:13+要申请媒体库权限,提前用expo-permissions申请:
import * as Permissions from 'expo-permissions';

const checkPermissions = async () => {
    const { status } = await Permissions.askAsync(Permissions.MEDIA_LIBRARY);
    return status === 'granted';
};

// 下载前先查权限
const hasPermission = await checkPermissions();
if (!hasPermission) {
    alert("得给文件访问权限才能保存");
    return;
}
  1. 私有目录看不到文件
    FileSystem.documentDirectory是App的私有目录,设备文件管理器里找不到!要让用户能看到,得把文件复制到公共目录(比如相册):
// 装expo-media-library:npm install expo-media-library
import * as MediaLibrary from 'expo-media-library';

const saveToPublicAlbum = async (fileUri, fileName) => {
    const { status } = await MediaLibrary.requestPermissionsAsync();
    if (status === 'granted') {
        const asset = await MediaLibrary.createAssetAsync(fileUri);
        await MediaLibrary.createAlbumAsync('MyDownloads', asset, false);
        alert("文件已经存到相册的MyDownloads文件夹啦");
    }
};

// 下载成功后调用这个方法
await saveToPublicAlbum(downloadResult.uri, fileName);

二、Fix CreateDownloadResumable的uuidv4错误

这个错是expo-modules-core版本不兼容或者没装对导致的,按下面步骤来:

  1. 升级expo-modules-core到最新版:
npm install expo-modules-core@latest
# yarn的话:yarn add expo-modules-core@latest
  1. 如果还是不行,手动导入uuid传进去:
// 先装uuid:npm install uuid
import { v4 as uuidv4 } from 'uuid';

// 创建可恢复下载时手动传uuid
const downloadResumable = FileSystem.createDownloadResumable(
    url,
    `${savePath}${fileName}`,
    {},
    (progress) => console.log(progress),
    uuidv4() // 手动生成uuid传进去
);
  1. 确保你的Expo SDK版本和expo-modules-core兼容,比如SDK 49+需要expo-modules-core >=1.5.0

额外提醒

  • 别用模拟器测缓存问题,拿真实设备测更准
  • 先确认你要下载的URL能直接在浏览器打开,有没有跨域或者防盗链限制
  • Android 10+如果还是有问题,在app.json的android配置里加:
"android": {
  "requestLegacyExternalStorage": true
}

内容的提问来源于stack exchange,提问作者Soludo Adigwerex

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 05:05:26