我想偶尔在电子邮件通知中发送大日志文件(>100MB)的最后2kB。现在,我正在尝试以下操作:
var endLogBytes = fs.statSync(logFilePath).size;
var endOfLogfile = fs.createReadStream(logFilePath, {start: endLogBytes-2000, end: endLogBytes - 1, autoClose: true, encoding: 'utf8'});
endOfLogfile.on('data', function(chunk) {
sendEmailFunction(chunk);
}
由于我刚刚重新启动,我的日志文件只有~2MB,但随着它们变大,我想知道:
1)读取数据是否需要很长时间(Node是否遍历整个文件,直到它到达我想要的字节,或者Node是否跳转到我想要的字节?)
2)消耗了多少内存?
3)何时释放内存空间?如何释放内存空间?
在这种情况下不应该使用ReadStream;因为它是一个流,它必须(我想)在到达最后2千字节之前研磨所有的前置数据。那么我就用fs.open
和fs.read
加上打开文件的描述符。像这样:
fs.open(logFilePath, 'r', function(e, fd) {
if (e)
throw e; //or do whatever you usually doing in such kind of situations
var endOfLogfile = new Buffer(2048);
fs.read(fd, endOfLogFile, endLogBytes-2048, 2048, null, function(e, bytesRead, data) {
if (e)
throw e;
//don't forget to data.toString('ascii|utf8|you_name_it')
sendEmailFunction(data.toString('ascii'));
});
});
更新:似乎当前ReadStream的实现足够智能,只读取所需的数据量。见:https://github.com/joyent/node/blob/v0.10.29/lib/fs.js L1550。它使用fs。打开和fs。阅读引擎盖下的内容。所以你可以毫无顾虑地使用ReadStream。不管怎样,我会选择fs open/read,因为它更显式,C-way,更好的风格等等。
关于内存和释放内存。您将需要至少2Mb的内存作为数据缓冲区+一些开销。我不认为有什么办法能准确地告诉我们需要多少管理费用。只需使用目标操作系统和节点版本进行测试即可。您可以使用此模块进行分析:https://www.npmjs.org/package/webkit-devtools-agent.
内存将被释放,当你不使用缓冲区的数据和GC将决定这是收集一些垃圾的好时机。GC是不确定的(即:不可预知的)。您不应该试图预测它的行为或以任何方式强制它进行垃圾收集。