一枪Streams

Dav*_*ave 2 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);
Run Code Online (Sandbox Code Playgroud)

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

谢谢

Mic*_*ley 5

Streams包含跟踪流状态的内部状态 - 在文件流的情况下,您有一个文件描述符对象,一个读缓冲区以及该文件已被读取的当前位置.因此,"倒带"Node.js流是没有意义的,因为Node.js是一个异步环境 - 这是一个要记住的重点,因为这意味着两个HTTP请求可以在中间同时处理.

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

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

您可以访问低级fs.read机制,因此理论上您可以创建一个仅打开单个文件描述符但生成多个流的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);
Run Code Online (Sandbox Code Playgroud)

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