download method

  1. @override
Future<AdapterResponse> download(
  1. AdapterRequest request,
  2. String savePath, {
  3. 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 download
  • savePath: The local file path where the downloaded file will be saved
  • onProgress: 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);
  }
}