'How do I use StreamedRequest in Dart http library to upload a file?
I want to upload a file via a non-multipart/form-data request like this:
POST http://127.0.0.1/upload
Cache-Control: no-cache
< /path/to/file/in/disk
(I tested and it successfully uploaded a file from JetBrain Rider's REST client to my REST endpoint.)
There is a StreamedRequest class in http package but I didn't find any constructor or setter to plug a byte stream or file content into it.
How do I use StreamedRequest to upload a file in Dart?
Solution 1:[1]
I'm just going to post phqb's solution in case the pastebin link goes down:
final file = new File(filePath);
final streamedRequest =
new http.StreamedRequest('POST', Configurations.getUserContentsApiUri('/upload'))
..headers.addAll({
'Cache-Control': 'no-cache',
'Authorization': 'Bearer $uploadToken',
});
streamedRequest.contentLength = await file.length();
file.openRead().listen((chunk) {
print(chunk.length);
streamedRequest.sink.add(chunk);
}, onDone: () {
streamedRequest.sink.close();
});
await streamedRequest.send();
print('after response');
Solution 2:[2]
Update:
A day after posting this I realized that this is not actually measuring the upload progress, but only the progress of reading the bytes from the local JSON payload, which is almost instantaneous. If/when I figure out how to actually measure the upload progress, I'll update this answer.
Original Answer:
This works for me:
import 'dart:convert';
import 'package:http/http.dart' as http;
// ...
final jsonPayload = {'base64File': 'abc123', 'something': 'else'};
// We are using a StreamedRequest so we can track the upload progress
final streamedRequest = http.StreamedRequest("POST", apiUri);
streamedRequest.headers['content-type'] = 'application/json';
// Length transferred (to calculate upload progress)
var transferredLength = 0;
// Upload progress (from 0.0 to 1.0)
var uploadProgress = 0.0;
// The stringified JSON payload
var stringEncodedPayload = jsonEncode(jsonPayload);
// Total length (to calculate upload progress)
var totalLength = stringEncodedPayload.length;
// Create a stream of the payload string
Stream.value(stringEncodedPayload)
// Transform the string-stream to a byte stream (List<int>)
.transform(utf8.encoder)
// Start reading the stream in chunks, submitting them to the streamedRequest for upload
.listen((chunk) {
transferredLength += chunk.length;
uploadProgress = transferredLength / totalLength;
print("Chunk: ${chunk.length}, transferred: $transferredLength, progress: $uploadProgress");
streamedRequest.sink.add(chunk);
}, onDone: () {
print("Done. Total: $totalLength, transferred: $transferredLength, progress: $uploadProgress");
streamedRequest.sink.close();
});
final result = await client.send(streamedRequest).then(http.Response.fromStream);
print("----------->");
print(result.statusCode);
print(result.body);
print("<-----------");
The output:
flutter: Chunk: 1024, transferred: 1024, progress: 0.0008807503580198599
flutter: Chunk: 1024, transferred: 2048, progress: 0.0017615007160397197
flutter: Chunk: 1024, transferred: 3072, progress: 0.0026422510740595796
...
flutter: Chunk: 1024, transferred: 1159168, progress: 0.9970094052784814
flutter: Chunk: 1024, transferred: 1160192, progress: 0.9978901556365013
flutter: Chunk: 1024, transferred: 1161216, progress: 0.9987709059945211
flutter: Chunk: 1024, transferred: 1162240, progress: 0.9996516563525409
flutter: Chunk: 405, transferred: 1162645, progress: 1.0
flutter: Done. Total: 1162645, transferred: 1162645, progress: 1.0
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Mark |
| Solution 2 |
