readline是Node.js里实现标准输入输出的封装好的模块,通过这个模块我们可以以逐行的方式读取数据流。
引入
const readline = require('readline')
创建readline实例
createInterface
创建实例,该实例的input属性值就是process.stdin
,output属性值是process.stdout
。
let r1 = readline.createInterface({
input: process.stdin,
output: process.stdout
})
注册事件监听和调用提问(question)方法
r1.question('你叫什么名字:',(result)=>{
console.log('我的名字是:',result)
r1.close() //当r1对象调用close()函数时,触发close事件
})
//close事件监听
r1.on("close", function () {
// 结束程序
process.exit(0);
})
1、createInterface里,需要传入标准输入输出作为数据的输入输出流
2、在question方法的回调函数里,可以获取到用户的输入并进行处理,同时进行了close操作来结束程序,否则程序不会结束
3、在close事件的监听里,执行了process.exit(0)来使程序退出的操作,因为readline模块只要一开始获取用户输入就不会结束,必须使用这种直接的方式来结束程序
示例1:创建package.json文件
模拟安装程序命令输入输出对应的信息,创建文件信息
// 创建实例
var rl = readline.createInterface({
input:process.stdin,
output:process.stdout
});
// 提问
function testQuestion(title){
return new Promise((resolve,inject) => {
rl.question(title,function(answer){
resolve(answer)
});
})
}
// 发起提问
async function createFile(){
const name = await testQuestion('您的包名是什么?')
const version = await testQuestion('版本号是多少?')
const description = await testQuestion('您的文件描述是什么?')
const entry = await testQuestion('您的入口文件是什么?')
const author = await testQuestion('您的包作者是什么?')
const content = `{
"name": "${name}",
"version": "${version}",
"description": "${description}",
"main": "${entry}",
"directories": {
"test": "test"
},
"scripts": {
"test": "echo Error: no test specified && exit 1"
},
"author": "${author}",
"license": "ISC"
}
`
fs.writeFile('./package.json', content, 'utf8', function (err) {
if (err) throw err;
console.log("写入成功")
rl.close();// 不加close,则不会结束
})
}
// 开始创建
createFile()
// close事件监听
rl.on("close", function(){
process.exit(0)// 结束程序
});
输出
您的包名是什么?readline
版本号是多少?1.0.0
您的文件描述是什么?readline测试
您的入口文件是什么?index.js
您的包作者是什么?huhao
写入成功
package.json
文件内容
{
"name": "readline",
"version": "1.0.0",
"description": "readline测试",
"main": "index.js",
"directories": {
"test": "test"
},
"scripts": {
"test": "echo Error: no test specified && exit 1"
},
"author": "huhao",
"license": "ISC"
}
示例2:输入输出
// 创建接口实例
let r1 = readline.createInterface({
input: process.stdin,
output: process.stdout
})
// 调用接口方法
r1.on("line", function (line) {
switch (line.trim()) {
case "copy":
console.log("输入了copy");
break;
case "hello":
r1.write("Hello "); // 自执行一次,相当于用户输入Hello
console.log("输入了hello");
break;
case "close":
console.log("输入了close");
r1.close();
break;
default:
console.log("没有找到命令!");
break;
}
})
// close事件监听
r1.on("close", function () {
console.log("再见");
process.exit(0);
})
输出
copy
输入了copy
hello
Hello 输入了hello
没有找到命令!
close
输入了close
再见
rl.write()
方法会写入数据到 readline 接口的 input,犹如它是用户提供的。
line
事件,这个事件就是在用户输完一行,按下回车后就会触发的事件,它会将用户输入的数据通过回调函数传回来,可在此方法里处理用户输入的数据
示例3:模拟命令行的输入输出
// 创建接口实例
let r1 = readline.createInterface({
input: process.stdin,
output: process.stdout
})
// setPromat(promat)给每一行设置一个提示符,
// 类似window命令行的> ,这里设置的是 请输入>
r1.setPrompt("请输入> ");
// prompt方法就是在等待用户输入数据
r1.prompt();
// 监听了'line' 事件,因为prompt方法调用一次就只会读取一次数据
// 所以,在这个方法内调用了一次prompt方法,这样就可以继续读取用户输入
// 从而达到一种命令行的效果
r1.on("line", function (line) {
switch (line.trim()) {
case "copy":
console.log("输入了copy");
break;
case "hello":
console.log("输入了hello");
break;
case "close":
console.log("输入了close");
r1.close();
break;
default:
console.log("没有找到命令!");
break;
}
r1.prompt();
});
// close事件监听
r1.on("close", function () {
console.log("再见");
process.exit(0);
})
输出
请输入> copy
输入了copy
请输入> in
没有找到命令!
请输入> hello
输入了hello
请输入> closh
没有找到命令!
请输入> close
输入了close
再见
这里
r1.setPrompt("请输入> ");
可以写在创建实例中
let r1 = readline.createInterface({
input: process.stdin,
output: process.stdout,
prompt: '请输入> '
})
示例4:逐行地读取文件流
const rl = readline.createInterface({
input: fs.createReadStream('./test/hello2.txt'),
crlfDelay: Infinity
});
rl.on('line', (line) => {
console.log(`文件的单行内容:${line}`);
});
输出
文件的单行内容:望岳
文件的单行内容:岱宗夫如何?
文件的单行内容:齐鲁青未了。
文件的单行内容:造化钟神秀,
文件的单行内容:阴阳割昏晓。
文件的单行内容:荡胸生曾云,
文件的单行内容:决眦入归鸟。
文件的单行内容:会当凌绝顶,
文件的单行内容:一览众山小。