How to read all binary from a HttpRequest, in Dart

2019-04-30 01:47发布

问题:

HttpRequest in Dart, is a Stream<List<int>>, how to get the binary content as List<int>?

I tried:

request.toList().then((data) {
    // but data is a List<List<int>> !!!
});

It seems I should not use toList. What's the correct method I should use?

回答1:

One way to do it is to set the onDone callback for listen(). The callback is fired when it has completed. Then just create a list of integers and add to it per every event:

List<int> data = [];
request.listen(data.addAll, onDone: () {
  // `data` has here the entire contents.
});

Alternatively, here's a one-liner:

request.reduce((p, e) => p..addAll(e)).then((data) {
  // `data` has here the entire contents.  
});

I'll also add Anders Johnsen's great tip of using BytesBuilder class, which I think you should prefer:

 request.fold(new BytesBuilder(), (b, d) => b..add(d)).then((builder) {
   var data = builder.takeBytes();
 });


回答2:

We recently added a BytesBuilder available in dart:io. See here for more info.

In your case the code could look like this:

request.fold(new BytesBuilder(), (builder, data) => builder..add(data))
    .then((builder) {
      var data = builder.takeBytes();
      // use data.
    });

The cool thing about using BytesBuilder is that it's optimized for large chunks of binary data. Note that I'm using takeBytes to get the internal buffer of the BytesBuilder, avoiding an extra copy.



回答3:

If you are using dart:html, you can use

HttpRequest.request('/blub.bin', responseType: 'arraybuffer').then((request) {

to get the response as one array buffer. You can access the buffer via request.response. But to access the bytes, you need to create a Uint8List represenation of the data:

List<int> bytes = new Uint8List.view(request.response);