Firebase Storage文件存在但无法下载 报No such file or directory
问题根因
报错和Firebase Storage云端文件是否存在无关:日志里HttpResult: 200已经说明云端文件请求成功,错误出在本地文件写入环节。
你直接拼接了包含receivedMyAppsDir子目录的本地文件路径,但没有提前创建这个子目录。Firebase Storage的writeToFile方法不会自动递归创建父级目录,尝试在不存在的目录下创建文件时,就会抛出java.io.IOException: No such file or directory异常。
另外你的异常捕获逻辑有漏洞:writeToFile返回的下载任务是异步的,你只监听了快照事件,既没有await等待任务执行完成,也没有给事件流加错误监听,导致下载抛出的异常变成未捕获的全局错误,外层的catch块根本接不到。
修复步骤
- 在生成本地文件对象前,先检查目标存储目录是否存在,不存在则递归创建:
final MyAppRef = _firebaseStorage.ref().child(MyAppURL); final dir = await getApplicationDocumentsDirectory(); // 拼接目标存储的父目录 final targetParentDir = Directory('${dir.path}/$receivedMyAppsDir'); // 目录不存在时递归创建所有层级 if (!await targetParentDir.exists()) { await targetParentDir.create(recursive: true); } final filename = '${targetParentDir.path}/${MyAppRef.name}'; final file = File(filename);
- 补全异步任务的异常捕获,避免未捕获报错:
try { final downloadTask = MyAppRef.writeToFile(file); // 监听快照事件的同时,处理流的异常 downloadTask.snapshotEvents.listen( (taskSnapshot) { switch (taskSnapshot.state) { case TaskState.running: print('##MyApp## downloadMyApp downloadTask running'); break; case TaskState.paused: print('##MyApp## downloadMyApp downloadTask paused'); break; case TaskState.success: print('##MyApp## downloadMyApp downloadTask success'); break; case TaskState.canceled: print('##MyApp## downloadMyApp downloadTask canceled'); break; case TaskState.error: print('##MyApp## downloadMyApp downloadTask error'); break; } }, onError: (e) { print('##MyApp## downloadMyApp ERROR from stream: ' + e.toString()); }, ); // 可选:await等待下载完成,方便后续处理下载结果 // await downloadTask; } catch (e) { print('##MyApp## downloadMyApp ERROR: ' + e.toString()); }
- 可选优化:路径拼接建议使用官方
path包提供的join方法,避免手动拼接字符串出现斜杠冗余、路径格式错误的问题。
内容的提问来源于stack exchange,提问作者whatwhatwhat
相关产品推荐
相关产品推荐

