downloadFile method
Downloads a file from a URL to a specified path.
If the file already exists and matches the expected size, download is skipped. Progress is reported via the download progress callback if one is set.
url
The URL to download the file from.
filePath
The local path where the file should be saved.
expectedSize
Optional expected file size for validation.
resourceName
Optional display name for the resource being downloaded.
Returns the downloaded File object.
Implementation
Future<File> downloadFile(
String url,
String filePath, {
int? expectedSize,
String? resourceName,
}) async {
final file = File(filePath);
final displayName = resourceName ?? p.basename(filePath);
if (await file.exists() && expectedSize != null) {
final fileSize = await file.length();
if (fileSize == expectedSize) {
if (_onDownloadProgress != null) {
_onDownloadProgress(displayName, expectedSize, expectedSize, 100.0);
}
return file;
}
}
await ensureDirectory(p.dirname(filePath));
try {
final client = http.Client();
final request = http.Request('GET', Uri.parse(url));
final response = await client.send(request);
if (response.statusCode == 200) {
final contentLength = response.contentLength ?? -1;
final sink = file.openWrite();
int received = 0;
int lastReportedPercentage = 0;
await response.stream.listen((data) {
sink.add(data);
received += data.length;
if (_onDownloadProgress != null && contentLength > 0) {
final percentage = (received / contentLength) * 100;
final reportPercentage =
(percentage ~/ _progressReportRate) * _progressReportRate;
if (reportPercentage > lastReportedPercentage) {
lastReportedPercentage = reportPercentage;
final clampedPercentage = max(0.0, min(percentage, 100.0));
_onDownloadProgress(
displayName,
received,
contentLength,
clampedPercentage,
);
}
}
}).asFuture<void>();
await sink.close();
client.close();
if (_onDownloadProgress != null && contentLength > 0) {
_onDownloadProgress(displayName, contentLength, contentLength, 100.0);
}
return file;
} else {
client.close();
throw Exception('Failed to download file: HTTP ${response.statusCode}');
}
} catch (e) {
debugPrint('Error downloading file from $url: $e');
rethrow;
}
}