download method
Future<AdapterResponse>
download(
- AdapterRequest request,
- String savePath, {
- ProgressCallback? onProgress,
override
Downloads a file from the server.
This method downloads a file and saves it to the specified path on the device.
Progress can be tracked using the optional onProgress callback.
Parameters:
request: The request configuration for the downloadsavePath: The local file path where the downloaded file will be savedonProgress: Optional callback to track download progress
Returns a Future that completes with an AdapterResponse when the download is complete.
Throws AdapterException if the download fails.
Example:
final request = AdapterRequest(
baseUrl: 'https://example.com',
path: '/files/document.pdf',
method: HttpMethod.get,
);
await adapter.download(
request,
'/path/to/save/document.pdf',
onProgress: (count, total) {
print('Downloaded: ${(count / total * 100).toStringAsFixed(1)}%');
},
);
Implementation
@override
Future<AdapterResponse> download(
AdapterRequest request,
String savePath, {
ProgressCallback? onProgress,
}) async {
try {
// 构建 URI
final uri = _buildUri(request);
// 构建头部
final headers = _buildHeaders(request);
// 创建请求
final httpRequest = http.Request('GET', uri);
httpRequest.headers.addAll(headers);
// 发送请求
final streamedResponse = await _client.send(httpRequest);
// 检查状态码
if (streamedResponse.statusCode >= 400) {
throw AdapterException(
message: 'HTTP ${streamedResponse.statusCode}',
type: AdapterExceptionType.response,
statusCode: streamedResponse.statusCode,
);
}
// 下载文件
final file = File(savePath);
final sink = file.openWrite();
var received = 0;
final total = streamedResponse.contentLength ?? 0;
await for (final chunk in streamedResponse.stream) {
sink.add(chunk);
received += chunk.length;
if (onProgress != null && total > 0) {
onProgress(received, total);
}
}
await sink.close();
// 转换头部
final responseHeaders = <String, List<String>>{};
streamedResponse.headers.forEach((key, value) {
responseHeaders[key] = [value];
});
return AdapterResponse(
statusCode: streamedResponse.statusCode,
statusMessage: streamedResponse.reasonPhrase,
data: savePath,
headers: responseHeaders,
request: request,
);
} catch (e, stackTrace) {
if (e is AdapterException) {
rethrow;
}
throw _convertException(e, stackTrace);
}
}