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?
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();