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

Flutter桌面端大文件分片下载存盘文件损坏问题求助

问题原因与解决方案

你的问题核心是流的背压处理缺失:stream.listen的回调是异步函数,但listen本身不会等待回调里的写入操作完成,新的数据块会直接触发下一次回调,导致多个写入操作并行执行。字节块的写入顺序被打乱,最终文件损坏、大小异常。小文件数据块少,大概率没触发并发写入冲突,所以没问题。

修复方案

方案1:用await for串行处理流

await for会逐个读取流中的数据块,必须等当前块写入完成后才会处理下一个,完美保证写入顺序:

final request = http.Request('GET', uri);
final streamedResponse = await request.send();
final pathToSave = File('C:\\Downloads\\test.zip');

// 先清空目标文件(如果需要覆盖已有文件)
await pathToSave.writeAsBytes([], mode: FileMode.write);

// 串行处理每个数据块
await for (final chunk in streamedResponse.stream) {
  await pathToSave.writeAsBytes(chunk, mode: FileMode.writeOnlyAppend, flush: true);
}

方案2:用asyncMap+drain确保串行执行

通过asyncMap将每个数据块的写入操作转为异步流,再用drain等待所有操作完成:

final request = http.Request('GET', uri);
final streamedResponse = await request.send();
final pathToSave = File('C:\\Downloads\\test.zip');

await pathToSave.writeAsBytes([], mode: FileMode.write);

await streamedResponse.stream
    .asyncMap((chunk) => pathToSave.writeAsBytes(chunk, mode: FileMode.writeOnlyAppend, flush: true))
    .drain(); // 等待所有流处理完成

额外优化

如果不需要每次写入都flush(频繁flush会降低写入速度),可以去掉flush: true,改为在所有数据写入完成后统一flush:

// 方案1优化版
await for (final chunk in streamedResponse.stream) {
  await pathToSave.writeAsBytes(chunk, mode: FileMode.writeOnlyAppend);
}
await pathToSave.flush();

内容的提问来源于stack exchange,提问作者alex smith

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 11:15:33