0
votes

I'm trying to save a large file from network to disk (160MB file). I'm saving the chunks as soon as they arrive but my saved file on disk is always corrupted and having variable size each time I re-run the script.

The reason I'm trying to save it as soon as a chunk has arrived is to save memory. I tried fetching the entire file and then save it, which caused my flutter to consume about 2GB of memory.

This is my code:

final request = http.Request('GET', uri);
final streamedResponse = await request.send();
File pathToSave = File('C:\\Downloads\\test.zip');

streamedResponse.stream.listen((value) async
{
    await pathToSave.writeAsBytes(value, mode: FileMode.writeOnlyAppend, flush: true);
})

I'm not sure but it seems the listen function doesn't wait for the previous callback to get finished and fires the next callback immediately and meddles with the previous file write. Same script works fine with small files.

Flutter 3.0.5 (desktop) Windows 11

streamedResponse.stream.pipe(out) where IOSink out = File('.....').openWrite() - pskink
Thank you. pipe works but since I wanted to also show download percentage, I used out.add(value) in the same function and it worked. The solution was to use IOSink which I didn't know about. You can post it as answer and I'll mark as solved. - alex smith
you don't need add - just use pipe but before you call it call map((e) { showPercentage(e); return e;}) - so it looks like streamedResponse.stream.map(...).pipe(out) - pskink
and it's even better if you do streamedResponse.stream.map(_showDownloadProgress).pipe(out) - where _showDownloadProgress is a method that shows the progress and simply returns it's input parameter without any changes - pskink
Alright yes that's even better. How would you do the error handling? With try catch? Because listen() comes with onError, onDone and cancelOnError. - alex smith