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

使用Expo DocumentPicker读取文件为Base64时遇位置不可读错误

Expo DocumentPicker读取Base64报错解决办法

[Error: Location 'file:///data/user/0/host.exp.exponent/cache/DocumentPicker/68f6fec2-feff-48e1-a0cc-d8fe5f54bc0b.pdf' isn't readable.]

在Expo SDK 48、最新版Expo Go的Android环境下,使用DocumentPicker选择PDF并尝试读取为Base64时会触发上述文件不可读错误,iOS端情况暂未明确。

解决步骤

1. 确认并申请存储权限

Android 13及以上版本需要额外的媒体读取权限,先在app.json中配置权限:

{
  "expo": {
    "permissions": [
      "READ_MEDIA_DOCUMENTS",
      "READ_EXTERNAL_STORAGE"
    ]
  }
}

然后在代码中主动请求权限:

import { requestPermissionsAsync, PermissionStatus } from 'expo-media-library';

// 在调用DocumentPicker前执行权限请求
const permissionResult = await requestPermissionsAsync({
  mediaLibrary: ['read'],
});

if (permissionResult.status !== PermissionStatus.GRANTED) {
  alert('需要授予存储读取权限才能处理文件');
  return;
}

2. 手动复制文件到可访问缓存目录

依赖copyToCacheDirectory自动复制可能因权限或写入问题失败,可手动复制文件后再读取:

import * as DocumentPicker from 'expo-document-picker';
import * as FileSystem from 'expo-file-system';

const pickFile = async () => {
  const file = await DocumentPicker.getDocumentAsync({
    type: "application/pdf",
    copyToCacheDirectory: false, // 关闭自动复制
  });

  if (file.type === "cancel") return;

  try {
    // 手动复制到Expo缓存目录
    const tempCacheUri = `${FileSystem.cacheDirectory}temp_file.pdf`;
    await FileSystem.copyAsync({
      from: file.uri,
      to: tempCacheUri,
    });

    // 读取复制后的文件为Base64
    const base64 = await FileSystem.readAsStringAsync(tempCacheUri, { encoding: "base64" });
    console.log(base64);
  } catch (error) {
    console.log(error);
    // 处理错误逻辑
  }
};

3. 提前校验文件是否存在

在读取前先检查缓存文件是否存在,避免因复制失败导致的报错:

// 获取文件信息后先校验
const fileInfo = await FileSystem.getInfoAsync(file.uri);
if (!fileInfo.exists) {
  console.log('目标文件不存在,复制可能失败');
  return;
}

内容的提问来源于stack exchange,提问作者Lucas Gardini Dias

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 01:20:25