'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 <文件名>');
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。