download method
Downloads url into path, replacing any file there only once the
download has finished.
Uses Nylo's NyApiService, so your interceptors apply. onProgress
receives bytes received and the total, or -1 when the server doesn't
say.
Implementation
Future<void> download(
String url,
String path, {
ProgressCallback? onProgress,
CancelToken? cancelToken,
Map<String, dynamic>? headers,
Map<String, dynamic>? queryParameters,
}) => _run(path, () async {
_guardWrite('download');
final String target = _resolve(path);
final NyApiService api = NyApiService(
useNetworkLogger: NyEnvRegistry.isInitialized ? null : false,
);
final Options options = Options(headers: {'Accept': '*/*', ...?headers});
final String? absolute = await driver.absolutePath(target);
if (absolute == null) {
final Response<List<int>> response = await api.dio.get<List<int>>(
url,
queryParameters: queryParameters,
cancelToken: cancelToken,
onReceiveProgress: onProgress,
options: options.copyWith(responseType: ResponseType.bytes),
);
await driver.write(target, response.data ?? const <int>[]);
_written(target);
return;
}
// Download next to the target under a hidden temp name, then rename it
// into place, so a half-finished download never looks complete.
final String folder = parentDiskPath(target);
final String temp = joinDiskPath(
folder,
'.${target.substring(folder.isEmpty ? 0 : folder.length + 1)}'
'${LocalDiskDriver.tempMarker}download-${_randomName(8)}',
);
await driver.createDirectory(folder);
try {
await api.download(
url,
savePath: (await driver.absolutePath(temp))!,
onProgress: onProgress,
cancelToken: cancelToken,
queryParameters: queryParameters,
options: options,
);
await driver.move(temp, target);
} catch (_) {
try {
await driver.delete(temp);
} catch (_) {}
rethrow;
}
_written(target);
});