Flutter中file_picker选取的文件不存在,如何获取有效File对象?
Flutter使用file_picker选取音频后无法获取有效File对象的解决方案
问题场景
使用file_picker包选取音频文件准备上传至AWS Storage时,发现返回的文件路径对应的文件不存在,验证代码及日志如下:
验证代码
FilePickerResult? pickedAudioResult = await FilePicker.platform .pickFiles(type: FileType.any, withData: true); if (pickedAudioResult == null) return; PlatformFile pickedFile = pickedAudio.files.single; print('Does file exist? ${await File(pickedFile.path!).exists()}'); print('File name: ${pickedFile.name}'); print('File extension: ${pickedFile.extension}'); print('File path: ${pickedFile.path}'); print('File size: ${pickedFile.size}');
日志输出
Does file exist? false File name: best ringtones - most romantic 2018.mp3 File extension: mp3 File path: /storage/emulated/0/Android/data/com.salamgram.salamgram/files/Ringtones/best ringtones - most romantic 2018.mp3 File size: 0
解决方法
利用
bytes生成临时有效文件
因为已设置withData: true,pickedFile.bytes会包含文件完整二进制数据,将其写入临时文件即可得到可正常使用的File对象:if (pickedFile.bytes != null) { final tempDir = await getTemporaryDirectory(); final tempFile = File('${tempDir.path}/${pickedFile.name}'); await tempFile.writeAsBytes(pickedFile.bytes!); // 验证临时文件有效性 print('Temp file exists? ${await tempFile.exists()}'); // 直接使用tempFile上传到AWS Storage即可 }需提前在
pubspec.yaml中添加path_provider依赖。大文件优先用
readStream处理
若音频文件体积较大,使用bytes会占用过多内存,建议开启withReadStream: true获取文件流,再写入临时文件:FilePickerResult? pickedAudioResult = await FilePicker.platform .pickFiles(type: FileType.any, withReadStream: true); if (pickedAudioResult != null) { PlatformFile pickedFile = pickedAudioResult.files.single; if (pickedFile.readStream != null) { final tempDir = await getTemporaryDirectory(); final tempFile = File('${tempDir.path}/${pickedFile.name}'); await tempFile.writeAsBytes(await pickedFile.readStream!.toBytes()); // 后续用tempFile执行上传操作 } }检查Android权限配置
确保AndroidManifest.xml中添加了必要的存储权限:<!-- Android 10及以下版本需添加 --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <!-- Android 11+访问公共存储需添加,该权限需用户手动授权 --> <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />避免直接依赖
path字段创建File
Android 10及以上采用分区存储机制,file_picker返回的path可能因应用无访问权限导致无法通过File类正常读取。优先使用bytes或readStream获取文件内容,而非直接用path实例化File对象。
内容的提问来源于stack exchange,提问作者sm-sayedi
相关产品推荐
相关产品推荐

