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

Flutter中使用Dio实现多文件下载的方法及替代方案咨询

问题

我已经用Dio包实现了单文件下载功能:

Future<void> downloadFile() async {
// 请求文件写入权限
bool hasPermission = await _requestWritePermission();
if (!hasPermission) return;

Dio dio = Dio();
try {
  var dir = await getApplicationDocumentsDirectory();
  await dio.download(uri, "${dir.path}/eng_json.json",
      onReceiveProgress: (rec, total) {
    print("路径 >>> " + "${dir.path}/eng_json.json");
    setState(() {
      downloading = true;
    });
  });
} catch (e) {
  print("错误 >>> " + e.toString());
}
setState(() {
  downloading = false;
  print("下载完成");
    });
  }

现在我需要下载多个文件,请问Dio包是否支持多文件下载?或者Flutter应用中有无处理多文件下载的更佳方案?

回答

Dio完全支持多文件下载,有两种常见实现方式:

  • 串行下载:通过循环逐个发起下载请求,适合文件数量不多、需要按顺序下载的场景。代码示例:
Future<void> downloadFilesSerially(List<String> urls, List<String> filenames) async {
  bool hasPermission = await _requestWritePermission();
  if (!hasPermission) return;
  
  Dio dio = Dio();
  var dir = await getApplicationDocumentsDirectory();
  
  setState(() => downloading = true);
  for (int i = 0; i < urls.length; i++) {
    try {
      await dio.download(
        urls[i],
        "${dir.path}/${filenames[i]}",
        onReceiveProgress: (rec, total) {
          print("正在下载 ${filenames[i]}: ${((rec/total)*100).toStringAsFixed(2)}%");
        }
      );
      print("${filenames[i]} 下载完成");
    } catch (e) {
      print("${filenames[i]} 下载失败: ${e.toString()}");
    }
  }
  setState(() => downloading = false);
  print("所有文件下载结束");
}
  • 并行下载:用Future.wait同时发起多个下载请求,效率更高,但要注意控制并发数(比如限制同时下载3-5个),避免请求过多导致异常。代码示例:
Future<void> downloadFilesParallel(List<String> urls, List<String> filenames) async {
  bool hasPermission = await _requestWritePermission();
  if (!hasPermission) return;
  
  Dio dio = Dio();
  var dir = await getApplicationDocumentsDirectory();
  
  setState(() => downloading = true);
  // 存储每个下载任务的Future
  List<Future<void>> downloadTasks = [];
  
  for (int i = 0; i < urls.length; i++) {
    final url = urls[i];
    final filename = filenames[i];
    downloadTasks.add(
      dio.download(
        url,
        "${dir.path}/$filename",
        onReceiveProgress: (rec, total) {
          print("${filename}: ${((rec/total)*100).toStringAsFixed(2)}%");
        }
      ).then((_) {
        print("${filename} 下载完成");
      }).catchError((e) {
        print("${filename} 下载失败: ${e.toString()}");
      })
    );
  }
  
  // 等待所有任务完成
  await Future.wait(downloadTasks);
  setState(() => downloading = false);
  print("全部下载完成");
}

针对复杂场景的更佳方案

如果需要后台下载、断点续传、下载管理等高级功能,可以使用专门的下载包:

  • flutter_downloader:支持多文件后台下载、进度跟踪、断点续传,还能在通知栏显示下载进度,适合需要长时间或后台下载的场景。
  • 实现思路:配置下载任务、监听下载状态、处理任务队列,比手动用Dio实现更省心。

另外,不管用哪种方式,都建议:

  • 给每个下载任务单独跟踪进度,避免用单一的downloading变量无法区分每个文件的状态;
  • 处理网络异常、存储权限变化等边缘情况;
  • 大量下载时考虑用Isolate隔离下载逻辑,避免阻塞UI线程。

内容的提问来源于stack exchange,提问作者Jaimin Modi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 04:26:05