一枪Streams

时间:2013-09-11 22:06:06

标签: node.js

以下内容无效:

var http = require('http');
var fs = require('fs');

var theIndex = fs.createReadStream('index.html');

http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/html'});
    theIndex.pipe(res);
}).listen(9000);

它将在第一个请求中运行良好,但对于所有后续请求,不会将index.html发送到客户端。 createReadStream调用似乎需要在createServer回调中。我想我可以概念化为什么,但你能用言语阐明原因吗?看来,一旦流完成,文件句柄就会关闭,必须再次创建流?它不能简单地“重新启动”?这是对的吗?

由于

1 个答案:

答案 0 :(得分:5)

Streams包含跟踪流状态的内部状态 - 在文件流的情况下,您有a file descriptor objecta read bufferthe current position the file has been read to。因此,“倒带”Node.js流是没有意义的,因为Node.js是一个异步环境 - 这是一个要记住的重点,因为这意味着两个HTTP请求可以在中间同时处理。

如果一个HTTP请求导致流开始从磁盘流式传输,并且在流式传输过程的中途另一个 HTTP请求进来,则无法在第二个HTTP请求中使用相同的流(内部记录保持会错误地将第二个HTTP响应发送错误的数据)。同样,在处理第二个HTTP请求时倒带流会导致将错误的数据发送到原始 HTTP请求。

如果Node.js 是异步环境,并且保证在重绕它之前流已完全用完,那么能够倒回流可能是有意义的(尽管有是其他考虑因素,例如openendclose事件的时间安排。

您可以访问low-level fs.read mechanisms,因此理论上您可以创建一个仅打开单个文件描述符但生成多个流的API;每个流都包含自己的缓冲区和读取位置,但共享文件描述符。也许是这样的事情:

var http = require('http');
var fs = require('fs');

var theIndexSpawner = createStreamSpawner('index.html');

http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/html'});
    theIndexSpawner.spawnStream().pipe(res);
}).listen(9000);

当然,你必须弄清楚什么时候关闭文件描述符,确保你没有持续太长时间等等。除非你发现多次打开文件是一个真正的瓶颈在你的应用程序中,它可能不值得精神开销。