Node.js逐行处理文件时避免末尾warning行追加多余换行
问题描述
需求为实现指定字符串是否位于文件末尾的判断,优化现有Node.js逐行日志处理代码。
现有代码引入fs、readline模块创建读取流,逐行遍历input.log文件内容,处理规则如下:
- 若行内容包含
warning,向output.log追加两个换行符 - 若行内容包含
error,将该行打印到控制台,同时追加写入output.log
现有实现代码:
const fs = require('fs'); const readline = require('readline'); const file = readline.createInterface({ input: fs.createReadStream('input.log'), output: process.stdout, terminal: false }); file.on('line', (line) => { if (line.includes('warning')) { fs.appendFile('output.log', '\r\n\r\n', err => { if (err) { console.error(err); } }); } else if (line.includes('error')) { console.log(line) fs.appendFile('output.log', line + "\r\n", err => { if (err) { console.error(err); } }); } });
代码可正常运行,但存在待优化点:当包含warning的行位于文件最后一行时,代码仍会追加两个换行符,产生多余空行,需要规避该场景下的无效写入。
实现方案
核心逻辑是延迟写入:读取行时不立刻执行文件写入,先缓存待写入内容,确认当前行不是最后一行后再落盘,所有行读取完成后单独处理最后一行的写入规则。
具体改动步骤:
- 新增
pendingWrite变量,暂存当前行对应的待写入内容 - 每次触发
line事件时,优先将上一轮缓存的待写入内容写入文件(触发新行读取时,上一行必然不是文件最后一行,可以正常写入),再根据当前行的匹配规则生成新的待写入缓存 - 监听readline实例的
close事件(所有文件内容读取完成时触发),此时缓存中存储的就是最后一行的待写入内容:如果内容是warning对应的两个换行符则直接丢弃,其余内容正常写入即可
修改后的完整代码:
const fs = require('fs'); const readline = require('readline'); const file = readline.createInterface({ input: fs.createReadStream('input.log'), output: process.stdout, terminal: false }); let pendingWrite = null; file.on('line', (line) => { // 写入上一行缓存的非末尾行内容 if (pendingWrite !== null) { fs.appendFile('output.log', pendingWrite, err => { if (err) console.error(err); }); } // 生成本行的待写入缓存 if (line.includes('warning')) { pendingWrite = '\r\n\r\n'; } else if (line.includes('error')) { console.log(line); pendingWrite = line + "\r\n"; } else { pendingWrite = null; } }); file.on('close', () => { // 处理最后一行,跳过warning产生的多余换行 if (pendingWrite && pendingWrite !== '\r\n\r\n') { fs.appendFile('output.log', pendingWrite, err => { if (err) console.error(err); }); } });
如果处理的日志文件体积较大,可以将所有待写入内容暂存在数组中,最终统一拼接后一次性写入,能减少多次IO调用带来的性能开销。
内容的提问来源于stack exchange,提问作者chillin
相关产品推荐
相关产品推荐

