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

React Native使用expo-file-system保存文件遇‘Could not create asset’错误

解决React Native Expo中MediaLibrary.createAssetAsync报错"Could not create asset"的问题

核心错误原因

  • MediaLibrary的定位限制:MediaLibrary主要用于管理图片、视频这类多媒体资源,Excel文件不属于系统媒体库默认支持的文件类型,调用createAssetAsync会直接失败。
  • 私有目录访问权限:FileSystem.documentDirectory是应用的私有沙盒目录,系统媒体库没有权限直接读取该目录下的文件,导致无法创建资产。
  • 下载文件完整性问题:如果API返回的文件损坏、为空,或者下载过程中出现中断,也会触发该错误。

解决方案

方案1:改用Expo Sharing让用户自主保存文件(推荐)

既然目标是保存Excel文件到设备,MediaLibrary不是合适的选择,用expo-sharing的shareAsync方法可以让用户选择保存位置,避免媒体库的格式限制:

import * as Sharing from 'expo-sharing';
import * as FileSystem from 'expo-file-system';

const handleDownload = async () => {
  try {
    const fileUri = FileSystem.documentDirectory + 'report.xlsx';
    const downloadResumable = FileSystem.createDownloadResumable(
      apiUrl,
      fileUri,
      {
        headers: {
          Authorization: `Bearer ${token}`,
          Accept: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
        },
      }
    );

    const { uri } = await downloadResumable.downloadAsync();

    // 检查文件是否存在且大小正常
    const fileInfo = await FileSystem.getInfoAsync(uri);
    if (!fileInfo.exists || fileInfo.size === 0) {
      throw new Error('下载的文件为空或损坏');
    }

    // 调用分享功能让用户选择保存位置
    await Sharing.shareAsync(uri, {
      mimeType: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
      dialogTitle: '保存Excel报告',
    });
    alert('文件已成功保存');
  } catch (error) {
    console.error('Error downloading file:', error);
    alert('下载或保存文件失败');
  }
};

方案2:复制文件到公共下载目录(针对Android/iOS公共目录)

如果需要自动保存到系统下载目录,可以先把私有目录的文件复制到公共目录,再通知系统扫描文件:

import * as FileSystem from 'expo-file-system';
import * as MediaLibrary from 'expo-media-library';

const handleDownload = async () => {
  try {
    const { status } = await MediaLibrary.requestPermissionsAsync();
    if (status !== 'granted') {
      alert('需要访问媒体库的权限!');
      return;
    }

    const privateUri = FileSystem.documentDirectory + 'report.xlsx';
    const downloadResumable = FileSystem.createDownloadResumable(
      apiUrl,
      privateUri,
      {
        headers: {
          Authorization: `Bearer ${token}`,
          Accept: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
        },
      }
    );

    const { uri } = await downloadResumable.downloadAsync();
    const fileInfo = await FileSystem.getInfoAsync(uri);
    if (!fileInfo.exists || fileInfo.size === 0) {
      throw new Error('下载的文件为空或损坏');
    }

    // 复制到公共下载目录
    const publicDownloadDir = FileSystem.downloadDirectory + 'report.xlsx';
    await FileSystem.copyAsync({
      from: uri,
      to: publicDownloadDir,
    });

    // 通知系统扫描文件,使其在文件管理器中可见
    await MediaLibrary.createAssetAsync(publicDownloadDir);
    alert('文件已保存至系统下载目录');
  } catch (error) {
    console.error('Error downloading file:', error);
    alert('下载文件失败');
  }
};

额外注意事项

  • 测试时确保API返回的Excel文件是完整有效的,可以先手动下载API链接验证文件是否能正常打开。
  • iOS上FileSystem.downloadDirectory对应系统的"文件"应用中的下载文件夹,Android则是公共下载目录。
  • 对于非多媒体文件,优先使用expo-sharing,避免和MediaLibrary的格式限制冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 15:03:24