我正在编写一个将图像上传到服务器的应用程序,我不希望仅显示微调框,而是希望能够获得该上传状态的进度。
此外,我想这样做而不使用Multipart表单数据。这是我当前正在使用的代码-但它似乎因管道中断而停滞了,对于是否将数据发送到服务器,我的反馈为零:
Future<String> _uploadFile(File assetFile) async {
final url = <removed>;
final stream = await assetFile.openRead();
int length = assetFile.lengthSync();
final client = new HttpClient();
final request = await client.postUrl(Uri.parse(url));
request.headers.add(HttpHeaders.CONTENT_TYPE, "application/octet-stream");
request.contentLength = length;
await request.addStream(stream);
final response = await request.close();
// response prociessing.
}
Run Code Online (Sandbox Code Playgroud)
是否可以将大数据作为流发送而无需将其读入内存,并且可以使用当前的dart / flutter API在上传中取得进展吗?
Cop*_*oad 13
屏幕截图(空安全):
这个解决方案
代码:
import 'package:http/http.dart' as http;
class _MyPageState extends State<MyPage> {
int _total = 0, _received = 0;
late http.StreamedResponse _response;
File? _image;
final List<int> _bytes = [];
Future<void> _downloadImage() async {
_response = await http.Client()
.send(http.Request('GET', Uri.parse('https://upload.wikimedia.org/wikipedia/commons/f/ff/Pizigani_1367_Chart_10MB.jpg')));
_total = _response.contentLength ?? 0;
_response.stream.listen((value) {
setState(() {
_bytes.addAll(value);
_received += value.length;
});
}).onDone(() async {
final file = File('${(await getApplicationDocumentsDirectory()).path}/image.png');
await file.writeAsBytes(_bytes);
setState(() {
_image = file;
});
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton.extended(
label: Text('${_received ~/ 1024}/${_total ~/ 1024} KB'),
icon: Icon(Icons.file_download),
onPressed: _downloadImage,
),
body: Padding(
padding: const EdgeInsets.all(20.0),
child: Center(
child: SizedBox.fromSize(
size: Size(400, 300),
child: _image == null ? Placeholder() : Image.file(_image!, fit: BoxFit.fill),
),
),
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
您已经在使用的Stream方式意味着您没有将整个文件读入内存。它可能以64k块的形式读取。
您可以使用StreamTransformer拦截生产者(文件)和消费者(HttpClient)之间的流,如下所示:
int byteCount = 0;
Stream<List<int>> stream2 = stream.transform(
new StreamTransformer.fromHandlers(
handleData: (data, sink) {
byteCount += data.length;
print(byteCount);
sink.add(data);
},
handleError: (error, stack, sink) {},
handleDone: (sink) {
sink.close();
},
),
);
....
await request.addStream(stream2);
Run Code Online (Sandbox Code Playgroud)
您应该看到byteCount以64k块递增。
尝试 dio库。该onSendProgress回调将是有益的。
例子:
response = await dio.post(
"http://www.example.com",
data: data,
onSendProgress: (int sent, int total) {
print("$sent $total");
},
);
Run Code Online (Sandbox Code Playgroud)
参考:https : //github.com/flutterchina/dio/issues/103
| 归档时间: |
|
| 查看次数: |
3358 次 |
| 最近记录: |