将图像文件有效地流式传输到HttpResponse

时间:2014-04-27 01:58:31

标签: dart dart-io dart-async

我的服务器端Dart网络应用程序为某些请求提供图像文件。

简化,以下是目前的工作:

   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();       
        });    
      }
   }

这很有效,但速度相当慢,我怀疑通过HttpResponse.writeCharCode单独写每个字节会让这里的事情变慢。

不幸的是,HttpResponse上没有.writeAllCharCodes这样的事情。那里有writeAll,但它在字节数组的每个元素上调用toString() - 我们需要写入原始字节。

有什么建议吗?

2 个答案:

答案 0 :(得分:3)

我认为这可能会对你有所帮助 - 我加速了大约4-5次:

我将在此处添加完整的示例:

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();       
    });
    */ 
  });
});

这可以解决您的问题吗?

此致 罗伯特

答案 1 :(得分:1)

考虑到@Anders Johnsen的评论,你可以这样做。

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

我个人喜欢这个,因为它使用了Darts方法级联,但都可以。