Stream image file to HttpResponse efficiently

2019-05-18 16:13发布

My server-side Dart web app serves image files for certain requests.

Simplified, here's what it currently does:

   HttpServer.bind(InternetAddress.ANY_IP_V4, 80)
    .then((HttpServer server) {    
      server.listen((HttpRequest request) {      
        request.response.statusCode = HttpStatus.OK;
        request.response.headers.contentType = ContentType.parse("image/jpg");
        var file = new File("C:\\images\\myImage.jpg");
        file.readAsBytes().then((List<int> bytes) {
          bytes.forEach((int b) => request.response.writeCharCode(b)); // slow!
          request.response.close();       
        });    
      }
   }

This works, but it's fairly slow and I suspect that writing every byte individually via HttpResponse.writeCharCode is what's slowing things down here.

Unfortunately, there's no such thing as .writeAllCharCodes on HttpResponse. There's writeAll, but it calls toString() on every element of the byte array - we need to write the raw bytes.

Any suggestions?

2条回答
仙女界的扛把子
2楼-- · 2019-05-18 16:37

Taking into account @Anders Johnsen's comment you could do this.

File f = new File( "image_file.png" )
  ..readAsBytes()
    .asStream()
    .pipe( req.response );

Personally I like this one because it makes use of Darts method cascading, but either works.

查看更多
Explosion°爆炸
3楼-- · 2019-05-18 16:42

I think this might help you - I got a speed up of about 4-5 times:

I will add my complete example here:

Future<ServerSocket> future = ServerSocket.bind("127.0.0.1", 1000);
future.then((ServerSocket sock) {
  HttpServer s = new HttpServer.listenOn(sock);

  s.listen((HttpRequest req) {
    req.response.statusCode = HttpStatus.OK;
    req.response.headers.contentType = ContentType.parse("image/png");
    var file = new File("someImage.png");

    // Average of about 5-7ms
    Future f = file.readAsBytes();
    req.response.addStream(f.asStream()).whenComplete(() {
      req.response.close();
    });
    // Average of ~25-30ms
    /*
    file.readAsBytes().then((List<int> bytes) {
      bytes.forEach((int b) => req.response.writeCharCode(b)); // slow!
      req.response.close();       
    });
    */ 
  });
});

Does this resolve your problem?

Regards Robert

查看更多
登录 后发表回答