Node.js的readline模块实现终端的输入输出

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}`);
});

输出

文件的单行内容:望岳
文件的单行内容:岱宗夫如何?
文件的单行内容:齐鲁青未了。
文件的单行内容:造化钟神秀,
文件的单行内容:阴阳割昏晓。
文件的单行内容:荡胸生曾云,
文件的单行内容:决眦入归鸟。
文件的单行内容:会当凌绝顶,
文件的单行内容:一览众山小。

 上一篇
浏览器事件循环EventLoop 浏览器事件循环EventLoop
看过很多关于JS Event Loop的文章和视频,在面试的时候,这个问题也逃不脱的,事件循环涉及的内容还是有点多的,这里自己在梳理下,以便加深自己的理解和记忆。 了解进程和线程 每当我们运行应用程序时,操作系统都会创建该应用程序的实例对象
2023-10-18
下一篇 
Node.js全局变量globals Node.js全局变量globals
全局对象 global 表示Node所在的全局环境,类似于浏览器的window对象。 console.log(global) 输出 <ref *1> Object [global] { global: [Circular
2023-10-15
  目录