Эффективно передавать файл изображения в HttpResponse

Мое серверное веб-приложение 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() на каждый элемент массива байтов - нам нужно записать необработанные байты.

Какие-либо предложения?


person Max♦    schedule 27.04.2014    source источник


Ответы (2)


Я думаю, это может вам помочь - я получил ускорение примерно в 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();       
    });
    */ 
  });
});

Это решает вашу проблему?

С уважением Роберт

person Robert    schedule 27.04.2014
comment
Просто хочу отметить, что res.addStream(stream).whenComplete(res.close) — это то же самое, что и stream.pipe(res). - person Anders Johnsen; 28.04.2014

Принимая во внимание комментарий @Anders Johnsen, вы можете сделать это.

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

Лично мне нравится этот, потому что он использует каскадный метод Darts, но любой из них работает.

person Hector    schedule 23.01.2015