downloadRaw method

Future<DownloadClientData> downloadRaw({
  1. required Uri url,
  2. required Directory? directoryDownload,
  3. required String? newFileName,
  4. Map<String, String>? headers,
  5. required bool isAutoDeleteDownloadClientData,
  6. required FutureOr onProggres(
    1. double proggres,
    2. File file
    ),
  7. required FutureOr onDone(
    1. DownloadClientData downloadClientData
    ),
})

Implementation

Future<DownloadClientData> downloadRaw({
  required Uri url,
  required Directory? directoryDownload,
  required String? newFileName,
  Map<String, String>? headers,
  required bool isAutoDeleteDownloadClientData,
  required FutureOr<dynamic> Function(double proggres, File file) onProggres,
  required FutureOr<dynamic> Function(DownloadClientData downloadClientData)
      onDone,
}) async {
  directoryDownload ??= directory_download;
  checkDir(directoryDownload: directoryDownload);
  Response response_head = await http_client.head(url, headers: headers);
  // response_head.printPretty();

  int downloadUntil = getContentLength(headers: response_head.headers);

  String new_file_name = [
        newFileName,
        getContentName(headers: response_head.headers),
        url.pathSegments.lastOrNull
      ].firstWhereOrNull(
          (element) => (element != null && element.trim().isNotEmpty)) ??
      "${url.toString()}";

  File file = File(path.join(directoryDownload.path, new_file_name));

  int downloadFrom = await Future(() async {
    if (file.existsSync()) {
      return await file.length();
    } else {
      await file.create(recursive: true);
    }
    return 0;
  });
  Completer<bool> completer = Completer<bool>();
  if (downloadUntil != 0) {
    if (downloadFrom == downloadUntil) {
      return DownloadClientData(
        date_time_start: DateTime.now(),
        file: file,
        uri: url,
        byteStream: ByteStream.fromBytes([]),
        completer: completer,
        is_failed: false,
        onData: (chunk) {},
        onDone: (downloadClientData) async {
          completer.complete(true);
          if (isAutoDeleteDownloadClientData) {
            deleteDownloadClientData(uri: url);
          }
          await onDone(downloadClientData);
        },
      );
    }
  }

  int downloaded = downloadFrom;

  Request request = Request('GET', (url));
  request.headers.addAll(
    {
      'Range': 'bytes=${downloadFrom}-${downloadUntil}',
    },
  );

  request.headers.addAll(headers ?? {});

  StreamedResponse streamedResponse = await http_client.send(request);

  RandomAccessFile randomAccessFile = await file.open(mode: FileMode.append);

  return DownloadClientData(
    date_time_start: DateTime.now(),
    file: file,
    uri: url,
    byteStream: streamedResponse.stream,
    completer: completer,
    is_failed: false,
    onData: (chunk) {
      double proggres = (downloaded / (downloadUntil) * 100);
      try {
        onProggres(proggres, file);
      } catch (e) {}
      randomAccessFile.setPositionSync(downloaded);
      randomAccessFile.writeFromSync(chunk);
      downloaded += chunk.length;
      if (downloaded == downloadUntil) {
        double proggres = (downloaded / (downloadUntil) * 100);
        try {
          onProggres(proggres, file);
        } catch (e) {}
      }
    },
    onDone: (downloadClientData) async {
      randomAccessFile.closeSync();
      completer.complete(true);

      if (isAutoDeleteDownloadClientData) {
        deleteDownloadClientData(uri: url);
      }

      await onDone(downloadClientData);
    },
  );
}