【发布时间】:2016-05-04 09:51:58
【问题描述】:
我使用 socket.io 和 fs.watch 函数在 node.js 中创建了 tail -f 的实现。
我使用fs.readFile 读取文件,将其转换为行数组并将其返回给客户端。将当前长度存储在变量中。
然后每当“文件更改”事件触发时,我重新读取整个文件,将其转换为行数组。然后比较旧长度和当前长度。像这样切片
fileContent.slice(oldLength, fileContent.length)
这给了我改变的内容。所以运行得很好。
问题:每次文件更改时我都会读取整个文件,如果文件太大,效率会降低。那么有没有什么办法,读取一个文件一次,如果有变化就获取变化的内容呢?
我也尝试过,为“tail -f”生成子进程
var spawn = require ('child_process').spawn;
var child = spawn ('tail', ['-f', logfile]);
child.stdout.on ('data', function (data){
linesArray = data.toString().split("\n")
console.log ( "Data sent" + linesArray[0]);
io.emit('changed', {
data: linesArray,
});
});
这个问题是:
- 当我通过写入一些内容保存日志文件时,on("data") 事件会多次触发。
- 首次加载时,它会正确返回文件的最后十行。但如果有变化,它会一次又一次地返回整个内容。
因此,如果您有任何解决此问题的想法,请告诉我。到那时我会挖掘互联网。
【问题讨论】:
-
你有没有考虑过使用像
tail这样的包? -
是的,但我宁愿坚持自己的实现,而不是依赖外部 npm 包。我想要本地的东西。
-
但是现有模块可以作为如何实现类似功能的示例。
-
是的,我正在阅读现有软件包的代码库。这就是我得到生成子进程代码的地方。我已经实现了这个功能。但只是想知道是否有办法避免每次更改时“读取文件”。这不是什么大事。
-
同意你的看法。但我是一种喜欢从头开始做事情的人,以获得对核心语言的更多见解,以便我下次可以轻松发明和调试。我从来没有直接使用过 jquery/Angular,首先我学习了 javascript。或者在进入 RoR 之前,我学习了 ruby 和 socket 编程。我喜欢从头开始创建东西,这样我就可以轻松地添加/扩展它的功能,因为我已经编写了它。如果我不需要它的大部分功能,我不想依赖库。有时我使用它,有时我不使用它:) 是的,我现在也只阅读改变的内容块。
标签: node.js socket.io readfile watch tail