breakPointDownload method
void
breakPointDownload({
- required String savePath,
- ProgressCallback? onReceiveProgress,
- Success? success,
- Failure? failure,
- Completed? completed,
- dynamic cancelCallback()?,
断点下载
Implementation
void breakPointDownload({
required String savePath,
ProgressCallback? onReceiveProgress,
Success? success,
Failure? failure,
Completed? completed,
Function()? cancelCallback,
}) async {
if (!(await _checkNetWork())) {
return;
}
int downloadStart = 0;
File file = File(savePath);
try {
final url = _buildFinalUrl();
if (file.existsSync()) {
downloadStart = file.lengthSync();
}
_options?.method = _httpType.name;
_options = _options?.copyWith(
responseType: ResponseType.stream,
);
if (_headers.isNotEmpty) {
_options?.headers?.addAll(_headers);
}
if (_enableGlobalHeader) {
_options?.headers ??= {};
_options?.headers?.addAll(_rxNet.getHeaders());
}
_options?.headers?.addAll({"Range": "bytes=$downloadStart-"});
// 准备请求体
dynamic requestBody = _rawBody;
if (_rawBody == null && _bodyParams.isNotEmpty) {
if (_bodyType == RequestBodyType.formData) {
requestBody = FormData.fromMap(_bodyParams);
} else if (_bodyType == RequestBodyType.json) {
requestBody = _bodyParams;
}
}
final response = await _rxNet.client!.request<ResponseBody>(
url,
options: _options,
cancelToken: _cancelToken,
data: requestBody,
queryParameters: _queryParams,
);
onResponse?.call(response);
RandomAccessFile raf = file.openSync(mode: FileMode.append);
Stream<Uint8List> stream = response.data!.stream;
final content = await getContentLength(response);
final total = int.tryParse(content?.split('/').last ?? "0") ?? 0;
final subscription = stream.listen((data) {
raf.writeFromSync(data);
downloadStart = downloadStart + data.length;
if (total < downloadStart) {
onReceiveProgress?.call(total, total);
return;
}
onReceiveProgress?.call(downloadStart, total);
}, onDone: () async {
success?.call(file, SourcesType.net);
await raf.close();
}, onError: (e) async {
failure?.call(e);
await raf.close();
}, cancelOnError: true);
_cancelToken?.whenCancel.then((_) async {
await subscription.cancel();
await raf.close();
cancelCallback?.call();
});
} on DioException catch (error) {
if (error.response != null) {
final content = await getContentLength(error.response!);
final total = int.tryParse(content?.split('/').last ?? "0") ?? 0;
if (total <= downloadStart) {
onReceiveProgress?.call(total, total);
success?.call(file, SourcesType.net);
}
}
if (CancelToken.isCancel(error)) {
cancelCallback?.call();
} else {
failure?.call(error);
}
}
completed?.call();
}