Flutter file_picker在Android返回损坏文件问题求助
Flutter file_picker 选取ZIP文件大小异常问题排查
问题现象
使用file_picker选取ZIP文件后,读取的文件大小远小于原文件,解压时抛出“Unexpected character”错误;但直接通过路径读取原文件夹中的同一ZIP文件时,大小正常且解压无问题。该问题在项目迁移至空安全后出现,已添加WRITE_EXTERNAL_STORAGE和READ_EXTERNAL_STORAGE权限。
核心原因推测
withData: true的内存限制:当设置withData: true时,file_picker会将文件内容加载到内存中(存储在bytes字段),同时生成的临时缓存文件可能仅包含部分数据(而非完整文件)。对于较大的ZIP文件,内存加载可能触发截断逻辑,导致缓存的文件路径指向不完整的文件,最终读取到错误的大小。- 空安全适配版本的行为变化:迁移空安全时若更新了
file_picker版本,新版本对withData参数的处理逻辑可能发生变化,旧代码的写法不再适配新行为。
解决方案
1. 移除withData: true参数
对于大文件,无需将数据预加载到内存,直接通过文件路径读取完整文件:
FilePickerResult? result = await FilePicker.platform.pickFiles( type: FileType.custom, allowedExtensions: ['zip'], // 移除withData: true,默认值为false ); if (result != null) { final File zipFileOne = File(result.files.single.path!); print('==== zipFile from picker: ${zipFileOne.lengthSync()}'); // 应输出正确大小 }
2. 若需直接操作文件数据,使用bytes字段
如果需要直接处理文件内容而非文件路径,使用result.files.single.bytes(确保文件大小在内存可承受范围内):
FilePickerResult? result = await FilePicker.platform.pickFiles( type: FileType.custom, allowedExtensions: ['zip'], withData: true, ); if (result != null) { final Uint8List zipBytes = result.files.single.bytes!; print('==== zip file bytes length: ${zipBytes.length}'); // 应等于原文件大小 // 使用bytes进行解压操作,而非通过path读取文件 }
3. 确认file_picker版本适配空安全
确保使用的file_picker版本为空安全兼容版(如^5.0.0及以上),避免版本不兼容导致的异常行为。
内容的提问来源于stack exchange,提问作者Dmitry
相关产品推荐
相关产品推荐

