You might need to download files to handle tasks in your applications. In this article, I will show guide you how to download files in Dart. This can be applied to Flutter, too.
Download files in Dart
By default, Dart language has provided developers a core class to handle the HTTT requests and responses to web server. So we can make use of this to download files from remote servers.
The HttpClient class
The class we’re looking for to use to handle HTTP requests and responses is HttpClient, which belongs to dart:io package.
Checkout the Important note from official documentation.
What does it mean?
Well, it means that we can also use any class of dart:io package for Flutter mobile apps development. That’s great!
Let’s get back to the HttpClient class. There is an example of how to make request and handle response with it.
HttpClient client = new HttpClient();
client.getUrl(Uri.parse("http://www.example.com/"))
.then((HttpClientRequest request) {
// Optionally set up headers...
// Optionally write to the request object...
// Then call close.
...
return request.close();
})
.then((HttpClientResponse response) {
// Process the response.
...
});
Okay, that’s what we’re going to use to download files from Internet.
Handle HTTP response
Since HttpClientResponse is simply a type of Stream<List<int>>, we can save them as raw bytes or transform into text if it is readable text-file.
1. Handle readable text file
To handle readable content, we need to transform it into text content, commonly UTF-8 format. This is how it works.
HttpClient client = new HttpClient();
client.getUrl(Uri.parse("https://fluttermaster.com/"))
.then((HttpClientRequest request) {
return request.close();
})
.then((HttpClientResponse response) {
response.transform(utf8.decoder).listen((contents) => print(contents));
});
To save into file, try following code.
HttpClient client = new HttpClient();
var _downloadData = StringBuffer();
var fileSave = new File('./index.html');
client.getUrl(Uri.parse("https://fluttermaster.com/"))
.then((HttpClientRequest request) {
return request.close();
})
.then((HttpClientResponse response) {
response.transform(utf8.decoder).listen((d) => _downloadData.write(d),
onDone: () {
fileSave.writeAsString(_downloadData.toString());
}
);
});
There is nothing special here. What you need to do is to handle response object returning from the HttpClient instance.
2. Handle binary files
Binary files are files that can’t be read as regular text files. It can be image files like JPG, PNG, GIF, or media file like MOV, MP4, MP3, AVI, or whatever …
To handle binary files, we need to process output as bytes.
HttpClient client = new HttpClient();
var _downloadData = List<int>();
var fileSave = new File('./logo.png');
client.getUrl(Uri.parse("https://fluttermaster.com/wp-content/uploads/2018/08/fluttermaster.com-logo-web-header.png"))
.then((HttpClientRequest request) {
return request.close();
})
.then((HttpClientResponse response) {
response.listen((d) => _downloadData.addAll(d),
onDone: () {
fileSave.writeAsBytes(_downloadData);
}
);
});
It is pretty much similar to handle readable content files, instead of string, we use byte.
Using stream pipe
If you feel tedious to use listen()
to handle stream, you can use pipe()
for convenience.
Here the sample:
HttpClient client = new HttpClient();
client.getUrl(Uri.parse("https://fluttermaster.com/wp-content/uploads/2018/08/fluttermaster.com-logo-web-header.png"))
.then((HttpClientRequest request) {
return request.close();
})
.then((HttpClientResponse response) {
response.pipe(new File('./logo_pipe.png').openWrite());
});
It works for all kinds of files, and it works as a generic file downloader.
Summary
Download files in Dart should be an easy task, and it really is.
Additionally, all above code is happened asynchronously, so it doesn’t block any next operations in your code.
All source code for this tutorial is put here on Github: https://github.com/petehouston/learn-dart/blob/master/bin/download_file.dart
If you have more tricks and tips to download files in Dart, please share to me, I’m curious about them, too.