共计 1061 个字符,预计需要花费 3 分钟才能阅读完成。
‘use strict’;
const fs = require(‘fs’);
/**
* tailf
*
* @param {String} filename 文件名
* @param {Number} delay 读取不到内容时等待的时间,ms
* @param {Function} onError 操作出错时的回调函数,onError(err)
* @param {Function} onData 读取到文件内容时的回调函数,onData(data)
*/
function tailf(filename, delay, onError, onData) {
// 每次读取文件块大小,16K
const CHUNK_SIZE = 16 * 1024;
// 打开文件,获取文件句柄
fs.open(filename, ‘r’, (err, fd) => {
if (err) return onError(err);
// 文件开始位置
fs.fstat(fd, (err, stats) => {
if (err) return onError(err);
// 文件开始位置
let position = stats.size;
// 循环读取
const loop = () => {
const buf = Buffer.alloc(CHUNK_SIZE);
fs.read(fd, buf, 0, CHUNK_SIZE, position,
(err, bytesRead, buf) => {
if (err) return onError(err);
// 实际读取的内容长度以 bytesRead 为准
// 并且更新 position 位置
position += bytesRead;
onData(buf.slice(0, bytesRead));
if (bytesRead < CHUNK_SIZE) {
// 如果当前已到达文件末尾,则先等待一段时间再继续
// setTimeout(loop, delay);
} else {
loop();
}
});
};
loop();
// 监听文件变化,如果收到 change 事件则尝试读取文件内容
fs.watch(filename, (event, filename) => {
if (event === ‘change’) {
loop();
}
});
});
});
}
const filename = process.argv[2];
if (filename) {
tailf(filename, 100, err => {
if (err) console.error(err);
}, data => {
process.stdout.write(data);
});
} else {
console.log(‘ 使用方法:node tailf < 文件名 >’);
}