rangDownload method
Future<CancelToken>
rangDownload(
- String url,
- String savePath, {
- Map<
String, dynamic> ? queryParameters, - required ProgressCallback? onProgress,
- VoidCallback? onDone,
- void onError(
- dynamic err
断点下载
Implementation
Future<CancelToken> rangDownload(
String url,
String savePath, {
Map<String, dynamic>? queryParameters,
required ProgressCallback? onProgress,
VoidCallback? onDone,
void Function(dynamic err)? onError,
}) async {
int start = 0;
final file = File(savePath);
if (file.existsSync()) {
start = file.lengthSync();
} else {
file.createIfNotExists(recursive: true);
}
final cancelToken = CancelToken();
try {
final response = await get<ResponseBody>(
url,
queryParameters: queryParameters,
options: Options(
responseType: ResponseType.stream,
followRedirects: false,
headers: {'range': 'bytes=$start-'},
),
);
final raf = file.openSync(mode: FileMode.append);
int received = start;
var rangHeader = response.headers.value(HttpHeaders.contentRangeHeader) ??
response.headers.value(HttpHeaders.contentLengthHeader);
if (rangHeader == null) throw Exception('获取文件长度失败!');
int total = int.tryParse(rangHeader.split('/').last) ?? 0;
final stream = response.data!.stream;
final subscription = stream.listen(
(data) {
raf.writeFromSync(data);
received += data.length;
onProgress?.call(received, total);
},
onDone: () async {
await raf.close();
onDone?.call();
},
onError: (err) async {
await raf.close();
onError?.call(err);
},
cancelOnError: true,
);
cancelToken.whenCancel.then((_) async {
await subscription.cancel();
await raf.close();
});
} on Exception catch (err) {
onError?.call(err);
}
return cancelToken;
}