我有以下文件我想逐行阅读并在找到“nameserver 8.8.8.8”后停止阅读。
nameserver 8.8.8.8
nameserver 45.65.85.3
nameserver 40.98.3.3
我正在使用nodejs和readline模块
const readline = require('readline');
const fs = require('fs');
function check_resolv_nameserver(){
// flag indicates whether namerserver_line was found or not
var nameserver_flag = false;
const rl = readline.createInterface({
input: fs.createReadStream('file_to_read.conf')
});
rl.on('line', (line) => {
console.log(`Line from file: ${line}`);
if (line === 'nameserver 8.8.8.8'){
console.log('Found the right file. Reading lines should stop here.');
nameserver_flag = true;
rl.close();
}
});
rl.on('close', function(){
if (nameserver_flag === true){
console.log('Found nameserver 8.8.8.8');
}
else {
console.log('Could not find nameserver 8.8.8.8');
}
});
}
check_resolv_nameserver();
因为我在读完第一个匹配后立即用rl.close()发出一个close事件,我希望我的Code只读取第一行然后再继续读取。但我的输出看起来像这样
Line from file: nameserver 8.8.8.8
Found the right file. Reading lines should stop here.
Found nameserver 8.8.8.8
Line from file: nameserver 45.65.85.3
Line from file: nameserver 40.98.3.3
如何在第一场比赛后让readline停止并让我继续其他内容?
答案 0 :(得分:1)
您也应关闭该流:
const readline = require('readline');
const fs = require('fs');
const readStream = fs.createReadStream('file_to_read.conf');
// More code here ...
const rl = readline.createInterface({
input: readStream
});
// Rest of your code
rl.close();
readStream.destroy();
答案 1 :(得分:1)
对于那些无法使linereader停止的人,请执行此操作(在您的readline回调中):
lineReader.close()
lineReader.removeAllListeners()
答案 2 :(得分:0)
我搜索了很长一段时间我没有机会让这个工作......所以我得到了我想要的东西归功于一个节点模块:line-reader
它很好,因为它可以从文件读取,也可以从缓冲区读取。
这是一个简单的代码示例,您可以在其中读取2行然后停止。
const lineReader = require('line-reader');
const stream = require('stream');
let bufferStream = new stream.PassThrough();
bufferStream.end(yourBuffer);
let lineNumber = 0;
lineReader.eachLine(bufferStream, function(line) {
lineNumber++;
if (lineNumber === 1 || lineNumber === 2) {
// Perform whatever
} else {
// returning false breaks the reading
return false;
}
}, async function finished (err) {
if (err) {
// throw error or whatever
}
// Do after reading processing here
});
编辑:我找到了一种干净的方式来完全按计划完成所有事情:
1st创建一个拆分器来读取字符串块
class Splitter extends Transform {
constructor(options){
super(options);
this.splitSize = options.splitSize;
this.buffer = Buffer.alloc(0);
this.continueThis = true;
}
stopIt() {
this.continueThis = false;
}
_transform(chunk, encoding, cb){
this.buffer = Buffer.concat([this.buffer, chunk]);
while ((this.buffer.length > this.splitSize || this.buffer.length === 1) && this.continueThis){
try {
let chunk = this.buffer.slice(0, this.splitSize);
this.push(chunk);
this.buffer = this.buffer.slice(this.splitSize);
if (this.buffer[0] === 26){
console.log('EOF : ' + this.buffer[0]);
}
} catch (err) {
console.log('ERR OCCURED => ', err);
break;
}
}
console.log('WHILE FINISHED');
cb();
}
}
然后将其传输到您的信息流:
let bufferStream = new stream.PassThrough();
bufferStream.end(hugeBuffer);
let splitter = new Splitter({splitSize : 170}); // In my case I have 170 length lines, so I want to process them line by line
let lineNr = 0;
bufferStream
.pipe(splitter)
.on('data', async function(line){
line = line.toString().trim();
splitter.pause(); // pause stream so you can perform long time processing with await
lineNr++;
if (lineNr === 1){
// DO stuff with 1st line
} else {
splitter.stopIt(); // Break the stream and stop reading so we just read 1st line
}
splitter.resume() // resumestream so you can process next chunk
}).on('error', function(err){
console.log('Error while reading file.' + err);
// whatever
}).on('end', async function(){
console.log('end event');
// Stream has ended, do whatever...
});
此代码可逐行启用完美的读取流。如果整个文件不长,则无需使用Splitter
答案 3 :(得分:0)
readline似乎会缓冲一些行,因此您必须添加自己的支票。
示例:
#! /usr/bin/node
const fs = require('fs')
const readline = require('readline')
const reader = readline.createInterface({
input: fs.createReadStream('test.js')
})
let wasRead = false
reader.on('line', line => {
if (wasRead) return undefined
console.log('hello world')
wasRead = true
reader.close()
})
答案 4 :(得分:0)
最适合我的是在暂停履历表上添加,让我在阅读后即可编辑文件。
var lineReader = require('readline').createInterface({
input: require('fs').createReadStream(require('path').resolve('test.js'))
});
lineReader.on('line', function (line) { console.log(line) }) /*loop all lines*/
.on('pause', function () {
/* resume after read lines is finished to close file */
lineReader.resume();
})
.on('close', function () {
/*action after file read is close*/
console.log('Close ok')
});
答案 5 :(得分:0)
您可以声明一个行事件侦听器并在需要时将其删除。
const lineEventListener = (line) => {
// do sth
// Close
rl.close();
rl.removeListener('line', lineEventListener);
}
rl.on('line', lineEventListener);