Skip to content

Instantly share code, notes, and snippets.

@ajmaln
Last active February 20, 2024 17:12
Show Gist options
  • Star 28 You must be signed in to star a gist
  • Fork 11 You must be signed in to fork a gist
  • Save ajmaln/c591cfb71d66bb6e688fe7027cbbe606 to your computer and use it in GitHub Desktop.
Save ajmaln/c591cfb71d66bb6e688fe7027cbbe606 to your computer and use it in GitHub Desktop.
Download file with progress in Dart/Flutter using 'http' package
import 'dart:typed_data';
import 'dart:io';
import 'package:http/http.dart';
import 'package:path_provider/path_provider.dart';
downloadFile(String url, {String filename}) async {
var httpClient = http.Client();
var request = new http.Request('GET', Uri.parse(url));
var response = httpClient.send(request);
String dir = (await getApplicationDocumentsDirectory()).path;
List<List<int>> chunks = new List();
int downloaded = 0;
response.asStream().listen((http.StreamedResponse r) {
r.stream.listen((List<int> chunk) {
// Display percentage of completion
debugPrint('downloadPercentage: ${downloaded / r.contentLength * 100}');
chunks.add(chunk);
downloaded += chunk.length;
}, onDone: () async {
// Display percentage of completion
debugPrint('downloadPercentage: ${downloaded / r.contentLength * 100}');
// Save the file
File file = new File('$dir/$filename');
final Uint8List bytes = Uint8List(r.contentLength);
int offset = 0;
for (List<int> chunk in chunks) {
bytes.setRange(offset, offset + chunk.length, chunk);
offset += chunk.length;
}
await file.writeAsBytes(bytes);
return;
});
});
}
@IlyaBlokh
Copy link

IlyaBlokh commented Apr 21, 2020

you have typo at final Uint8List bytes = Uint8List(r.ntentLength);
and missing }); at the end

@ajmaln
Copy link
Author

ajmaln commented Apr 21, 2020

you have typo at final Uint8List bytes = Uint8List(r.ntentLength);
and missing }); at the end

@IlyaBlokh, thanks for spotting that, updated.

@lucaswilms
Copy link

You're also missing as http in line 4.
It should be import 'package:http/http.dart' as http;.

@A7md-Elkassas
Copy link

ineed to use the value to preview on the screen with progress bar any idea how to do it

@ajmaln
Copy link
Author

ajmaln commented Oct 17, 2020

ineed to use the value to preview on the screen with progress bar any idea how to do it

@A7md-Elkassas
You can use a setState instead where I have given written a debugPrint in the code to store the percentage on a state variable, which you can pass as an argument to a widget.

@A7md-Elkassas
Copy link

A7md-Elkassas commented Oct 17, 2020

ineed to use the value to preview on the screen with progress bar any idea how to do it

@A7md-Elkassas
You can use a setState instead where I have given written a debugPrint in the code to store the percentage on a state variable, which you can pass as an argument to a widget.

thank you for answering i have a code for uploading but when i press upload button the percentage inceases if it's 100 its increases to 200
content of uploading function

var url = Uri.parse("http://192.168.1.3/file_upload.php");
    var request = http.MultipartRequest("POST", url);
    request.files.add(http.MultipartFile.fromBytes('file', _pickedFile,
        filename: input.files.first.name));
    var send = request.send();
    send.asStream().listen((http.StreamedResponse r) {
      r.stream.listen((List<int> chunk) {
      
        actualPercentage = percentage / r.contentLength * 100;
        print(r.contentLength);

        chunks.add(chunk);
        percentage += chunk.length;
      }, onDone: () async {
        // Display percentage of completion
        actualPercentage = percentage / r.contentLength * 100;
        if (percentage < 100) {
          setState(() {
            uploadMsg = 'uploading ${actualPercentage.toString()}%';
          });
        } else {
          setState(() {
            uploadMsg = 'Successfully Uploaded';
          });
        }
      });
    });

variables

double actualPercentage = 0;
  double percentage = 0;
  String uploadMsg = '';

 List<List<int>> chunks = new List();

@JohnGalt1717
Copy link

This really should stream the chunks into the file as it goes instead of holding them in memory.

@flutternoob
Copy link

How to implement error handling? I tried implementing onError: (handleError), where i try to show a snackbar if download fails due to loss of internet connection ,but its not working.

@JohnGalt1717
Copy link

@flutternoob My solution was to wrap the entire thing in an try/catch

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment