How to adjust download buffer size on flutter http, dio or flutter_downloader?
Asked Answered
A

1

7

enter image description here

I want to download a large file that is amount of about 300MB. It was a lot slower than I thought, and when I looked at the log, I saw that it was fetching bytes with a size of about 8KB. I haven't found a way to resize the download buffer even if I look for other flutter libraries. How can I adjust that?

Abramson answered 22/5, 2020 at 13:32 Comment(3)
I think this has to be done with the underlying HttpClient or Socket. I would suggest testing this without Flutter and Dio in a simple main function with pure dart:io and see where this gets you.Proverbial
same issue hereProfession
Same issue here, can't seem to find a fixLubet
R
4

You can use the ChunkedStreamReader to handle the response stream using a custom chunkSize (e.g. 64KB) and write it to a file. See also this GitHub issue.

In the below example it will listen to the response as a stream then read the bytes from the ChunkedStreamReader with the wanted chunk size (64*1024 = 64KB) and write the gotten chunks to a file.

// Download file
try {
  int offset = 0;
  var httpClient = http.Client();
  var request = http.Request('GET', Uri.parse(url));
  var response = httpClient.send(request);

  // Open file
  File file = File('$downloadPath.tmp');

  response.asStream().listen((http.StreamedResponse r) async {
    final reader = ChunkedStreamReader(r.stream);
    try {
      // Set buffer size to 64KB
      int chunkSize = 64 * 1024;
      Uint8List buffer;
      do {
        buffer = await reader.readBytes(chunkSize);
        // Add buffer to chunks list
        offset += buffer.length;
        print('Downloading $filename ${downloaded ~/ 1024 ~/ 1024}MB');
        // Write buffer to disk
        await file.writeAsBytes(buffer, mode: FileMode.append);
      } while (buffer.length == chunkSize);

      // Rename file from .tmp to non-tmp extension
      await file.rename(downloadPath);
      print('Downloaded $filename');
    } catch (e) {
      print(e);
    } finally {
      reader.cancel();
    }
  }).onDone(() async {
    // do something when finished
  });
} catch (error) {
  print('Error downloading: $error');
}

EDIT: 12/03/2022

I just published a package for that on pub.dev (Chunked_Downloader) where you can define the chunk size in the constructor:

var chunkedDownloader = await ChunkedDownloader(
    url: 'https://example.com/video.mjpeg',
    savedDir: '/temp',
    fileName: 'sometestfile.mjpeg',
    chunkSize: 1024 * 1024,
    onError: (error) {},
    onProgress: (received, total, speed) {},
    onDone: (file) {})
.start();
Rechabite answered 9/6, 2022 at 7:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.