使用Node.JS I / O编写日志数据时出错
我将Node.JS与一个提供对数据的迭代器式访问的库进行交互:
next = log.get_next()
我有效地想写下面的内容:
while (next = log.get_next()) { console.log(next); }
并将stdout
redirect到一个文件(例如, node log.js > log.txt
)。 这适用于小日志,但对于大量的输出文件是空的,我的内存使用率通过屋顶。
看来我并不完全理解节点中的I / O,因为向控制台写入string的简单无限循环也performance出相同的行为。
一些关于如何完成这个任务的build议是非常棒的。 谢谢。
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
你会看到文件周期性增长,内存达到稳定状态。
你接口的库应该接受callback。 Node.js被devise为非阻塞的。 我认为,也许console.log
保持返回控制循环(和log.get_next()
)在发送输出之前。
如果重写模块以使get_next支持callback,则改进后的代码可能如下所示:
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();