无法使用Node.JS I / O写入日志数据

时间:2011-05-16 03:40:33

标签: node.js

我正在将Node.JS与一个提供对数据进行迭代器式访问的库连接:

next = log.get_next()

我实际上想写下以下内容:

while (next = log.get_next()) {
    console.log(next);
}

并将stdout重定向到文件(例如node log.js > log.txt)。这适用于小型日志,但对于大型批次,输出文件为空,我的内存使用量通过屋顶。

看起来我并不完全理解节点中的I / O,因为将字符串写入控制台的简单无限循环也表现出相同的行为。

关于如何完成这项任务的一些建议会很棒。感谢。

2 个答案:

答案 0 :(得分:2)

WriteStream类缓冲i / o,如果你永远不会产生线程,那么排队的写操作永远不会得到服务。最好的方法是编写一个合理的数据块,然后在再次写入之前等待缓冲区清除。 WriteStream类发出一个'drain'事件,告诉你缓冲区何时被完全刷新。这是一个例子:

var os = require('os');

process.stdout.on('drain', function(){
  dump();
});

function dump(){
  for (var i=0; i<10000; i++)
    console.log('xxxx');
  console.error(os.freemem());
}

dump();

如果您的运行方式如下:

node testbuffer > output

你会看到文件定期增长,内存达到稳定状态。

答案 1 :(得分:0)

您正在接口的库应该接受回调。 Node.js设计为非阻塞。我想也许console.log在发送输出之前可能会继续将控制权返回给循环(和log.get_next())。

如果重写模块以使get_next支持回调,改进的代码可能是这样的:

var log_next = function() {
  console.log(next);
  log.get_next(log_next);
};
log.get_next(log_next);

(有一些库和模式可以使这段代码更漂亮。)

如果代码只是同步并且必须保持原样,那么使用0或其他小数字调用setTimeout可以防止它阻塞整个过程。

var log_next = function() {
  console.log(log.get_next());
  setTimeout(log_next, 0);
};
log_next();