突破上传瓶颈:Flutter分片上传与断点续传实战方案
你是否遇到过几十MB的文件上传超时?是否因网络中断导致几小时的上传前功尽弃?在移动应用开发中,大文件上传一直是困扰开发者的难题。本文基于Flutter Go项目的[网络工具类](https://link.gitcode.com/i/d4f0c893432ba6c8e468e621439c92bb),手把手教你实现分片上传与断点续传功能,让大文件传输变得简单可靠。## 大文件上传的痛点与解决方案..
突破上传瓶颈:Flutter分片上传与断点续传实战方案
你是否遇到过几十MB的文件上传超时?是否因网络中断导致几小时的上传前功尽弃?在移动应用开发中,大文件上传一直是困扰开发者的难题。本文基于Flutter Go项目的网络工具类,手把手教你实现分片上传与断点续传功能,让大文件传输变得简单可靠。
大文件上传的痛点与解决方案
传统单文件上传在处理超过10MB的文件时,常常面临三大问题:网络波动导致上传失败、服务器超时限制、流量浪费。而分片上传(将文件分割为小块传输)与断点续传(记录上传进度实现中断恢复)的组合方案,能完美解决这些痛点。
Flutter Go作为包含140+组件的开发工具包,其网络模块已提供基础HTTP请求能力。我们将基于此扩展实现高级上传功能,整个方案包含四个核心步骤:
分片上传核心实现
文件分块策略
将大文件分割为固定大小的块(建议2-5MB),使用Dio库的MultipartFile实现分块上传。以下是基于Flutter Go现有网络工具类的扩展代码:
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:flutter_go/utils/net_utils.dart';
class UploadService {
// 分块大小2MB
static const int CHUNK_SIZE = 2 * 1024 * 1024;
// 分片上传方法
static Future uploadByChunk(String filePath) async {
File file = File(filePath);
int fileSize = await file.length();
int chunkCount = (fileSize / CHUNK_SIZE).ceil();
for (int i = 0; i < chunkCount; i++) {
int start = i * CHUNK_SIZE;
int end = (i + 1) * CHUNK_SIZE;
if (end > fileSize) end = fileSize;
// 读取文件分块
List<int> chunkData = await file.readAsBytes(start: start, end: end);
// 使用Flutter Go现有网络工具类上传
FormData formData = FormData.fromMap({
'file': MultipartFile.fromBytes(chunkData,
filename: 'chunk_$i',
contentType: MediaType('application', 'octet-stream')
),
'chunkIndex': i,
'totalChunks': chunkCount,
'fileName': file.path.split('/').last
});
await NetUtils.post('/upload/chunk', formData);
}
// 通知服务器合并文件
return await NetUtils.post('/upload/merge', {
'fileName': file.path.split('/').last,
'totalChunks': chunkCount
});
}
}
分块上传流程示意
上图展示了将一个10MB的图片文件分割为5个2MB分块的上传过程,每个分块独立传输,即使某块失败也只需重传该分块。
断点续传实现方案
上传进度记录
利用Flutter Go的本地存储工具记录每个文件的上传进度,实现断点续传:
import 'package:flutter_go/utils/shared_preferences.dart';
class UploadProgressManager {
// 保存上传进度
static Future saveProgress(String filePath, int chunkIndex) async {
SpUtil sp = await SpUtil.getInstance();
await sp.putInt('upload_${filePath}_progress', chunkIndex);
}
// 获取上次上传进度
static Future<int> getLastProgress(String filePath) async {
SpUtil sp = await SpUtil.getInstance();
return sp.getInt('upload_${filePath}_progress') ?? 0;
}
// 清除进度记录
static Future clearProgress(String filePath) async {
SpUtil sp = await SpUtil.getInstance();
await sp.remove('upload_${filePath}_progress');
}
}
断点续传工作流程
当上传中断后,下次上传时通过getLastProgress获取已上传的分块索引,从该位置继续上传:
// 断点续传实现
static Future resumeUpload(String filePath) async {
int lastChunk = await UploadProgressManager.getLastProgress(filePath);
File file = File(filePath);
int fileSize = await file.length();
int chunkCount = (fileSize / CHUNK_SIZE).ceil();
// 从上次中断位置继续上传
for (int i = lastChunk; i < chunkCount; i++) {
// ...分块上传代码同上...
// 上传成功后记录进度
await UploadProgressManager.saveProgress(filePath, i);
}
// 上传完成清除进度记录
await UploadProgressManager.clearProgress(filePath);
return await NetUtils.post('/upload/merge', {/*...*/});
}
Flutter Go集成完整步骤
步骤1:添加依赖
在pubspec.yaml中添加Dio依赖(如果尚未添加):
dependencies:
dio: ^4.0.6
shared_preferences: ^2.2.2
步骤2:扩展网络工具类
修改net_utils.dart,添加分块上传支持:
// 在NetUtils类中添加
static Future uploadChunk(String url, FormData data) async {
Directory documentsDir = await getApplicationDocumentsDirectory();
String documentsPath = documentsDir.path;
var dir = Directory("$documentsPath/cookies");
await dir.create();
dio.interceptors.add(CookieManager(PersistCookieJar(dir: dir.path)));
// 添加超时和取消支持
CancelToken cancelToken = CancelToken();
dio.options.connectTimeout = 60000; // 分块上传超时设为60秒
var response = await dio.post(url, data: data, cancelToken: cancelToken);
return response.data;
}
步骤3:使用上传组件
集成完成后,可通过Flutter Go的文件选择组件选择大文件,调用UploadService.resumeUpload实现断点续传功能。上图展示了上传进度条组件的实际效果。
性能优化与注意事项
- 分块大小选择:根据服务器配置调整分块大小,太小会增加请求次数,太大会导致单个分块上传失败风险
- 并发上传控制:可使用
Future.wait控制同时上传的分块数量,避免过多请求导致网络拥堵 - 错误重试机制:实现分块上传失败自动重试逻辑,建议最多重试3次
- 文件校验:上传完成后通过MD5校验确保文件完整性
总结与扩展
通过本文介绍的分片上传与断点续传方案,你可以基于Flutter Go现有架构轻松实现大文件上传功能。核心要点包括:
- 利用分块策略将大文件拆分传输
- 使用本地存储记录上传进度
- 基于现有网络工具类扩展上传能力
该方案已在实际项目中验证,可稳定传输100MB以上的视频文件。下期我们将介绍如何实现上传进度的实时可视化和后台上传功能,敬请关注!
官方文档:Flutter Go网络模块
更多推荐


所有评论(0)