javascript - `open` 和 `error` 同时与 fs.createReadStream() 和 EISDIR

标签 javascript node.js stream

在实现简单的静态服务中间件时,我偶然发现了以下代码:

fs = require('fs');
util = require('util');

stream = fs.createReadStream('/');
stream.on('open', function(fd) { console.log('opened! ' + util.inspect(fd)); });
stream.on('error', function(err) { console.log('error! ' + util.inspect(err)); });

当参数是目录时,openerror 事件都会被触发!

$ node test.js 
opened! 11
error! { [Error: EISDIR, read] errno: 28, code: 'EISDIR' }

我假设我有 openerror,从来没有同时发生过。

什么是区分openopen 而不求助于显式测试 fdstat 是目录?还有其他类似的案例吗?

最佳答案

当您在 Node 中创建可读流时,代码将尝试打开文件并读取内容(如果未提供 fd)。你可以通过代码看到:

调用createReadStream()会创建一个ReadStream对象,如果fd,它将调用this.open()不是数字(link to source):

if (!util.isNumber(this.fd))
  this.open();

这会调用 fs.open,我猜这会在目录上打开目录? (这有点奇怪为什么允许它没有错误地工作,但代码最终会命中 native 绑定(bind)层并继续。)打开它后,代码发出“打开”事件并开始读取内容文件(link to source):

ReadStream.prototype.open = function() {
  var self = this;
  fs.open(this.path, this.flags, this.mode, function(er, fd) {
    if (er) {
      if (self.autoClose) {
        self.destroy();
      }
      self.emit('error', er);
      return;
    }

    self.fd = fd;
    self.emit('open', fd);
    // start the flow of data.
    self.read();
  });
};

在调用 fs.read 期间导致错误,该错误被发送到 ReadStream 的回调 onRead ( link to source ) :

function onread(er, bytesRead) {
  if (er) {
    if (self.autoClose) {
      self.destroy();
    }
    self.emit('error', er);

因为 createReadStream 调用立即打开并开始读取文件内容(如果未传递文件描述符),事件将如您​​所见发出。首先是 open 事件,然后尝试读取文件,但失败了,并且发出了 error 事件。

因为这是一个 readable stream ,你可能需要考虑监听 data 事件而不是 open 事件来判断这是否是一个可接受的文件,因为你是立即阅读。类似这样的东西:

fs = require('fs');
util = require('util');

stream = fs.createReadStream('/');
stream.on('data', function(chunk) { console.log('data! ' + chunk.toString()); });
stream.on('error', function(err) { console.log('error! ' + util.inspect(err)); });

在测试中,您将在文件上点击 data,在目录上点击 error

关于javascript - `open` 和 `error` 同时与 fs.createReadStream() 和 EISDIR,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24377582/

相关文章:

python - 将 io.StringIO 转换为 io.BytesIO

node.js - Mocha 测试中的上下文未定义

javascript - 将上下文与 api 调用一起用于根级组件

javascript - CSS -webkit-filter 在 Chrome 22.0 中不起作用

javascript - 如何传递 react 列表项以作为 onClick 的参数

node.js socket.write() 不适用于 if 条件

node.js - Loopback "Include"过滤器因 hasManyThrough 关系而失败

c# - 基于自定义属性的 IHostBufferPolicySelector

macos - 在 Swift 中逐行读取文件/URL

javascript - 动态添加的 dom 元素不响应 jQuery 函数