I need to be able to download and display an image from a private server. The request that I send needs to include a header with content-type and a body with sessionToken and userId. The server responds with a binary stream with the Content-type application/octet-stream.
This is the code I have right now:
Future<Null> _downloadFile(String url, String userId, sessionToken) async {
Map map = {'token': sessionToken, 'UserId': userId};
try {
var request = await httpClient.getUrl(Uri.parse(url));
request.headers.set('content-type', 'application/json');
request.add(utf8.encode(json.encode(map)));
var response = await request.close();
var bytes = await consolidateHttpClientResponseBytes(response);
await _image.writeAsBytes(bytes);
userImage(_image);
}
catch (value){
print(value);
}
}
When I try to read the response I get this error: HttpException: Content size exceeds specified contentLength. 72 bytes written while expected 0.
I've tried to google this endlessly on how to download a file from a server using a stream, but I can't find anything. What I need is something similar to the bitmap class in .NET that can take in a stream and turn it into an image.
Can anybody help me? It would be greatly appreciated.
I was able to do this successfully with this code:
void getImage(String url, String userId, sessionToken) async{
var uri = Uri.parse(url);
Map body = {'Session': sessionToken, 'UserId': userId};
try {
final response = await http.post(uri,
headers: {"Content-Type": "application/json"},
body: utf8.encode(json.encode(body)));
if (response.contentLength == 0){
return;
}
Directory tempDir = await getTemporaryDirectory();
String tempPath = tempDir.path;
File file = new File('$tempPath/$userId.png');
await file.writeAsBytes(response.bodyBytes);
displayImage(file);
}
catch (value) {
print(value);
}
}
Thanks for the help :)
Here is a related example showing only how to stream the content of a webpage or file:
import 'package:http/http.dart' as http;
Future<void> main() async {
final url = Uri.parse('https://google.com/');
final client = http.Client();
final request = http.Request('GET', url);
final response = await client.send(request);
final stream = response.stream;
await for (var data in stream) {
print(data.length);
}
client.close();
}
It is a complete example so if you add the http package to your pubspec.yaml file, you can copy the whole thing to test it. The example prints the size of each data chunk coming in. If you want to convert those bytes to a string you could use stream.transform(utf8.decoder)
.
I'm using the above example to learn how streaming works. A more complete solution would need to handle errors and save the file.
Thanks to this answer for help with this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With