使用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
相关产品推荐
相关产品推荐

