Node.js API详解之 readline模块用法详解

(编辑:jimmy 日期: 2024/12/31 浏览:2)

本文实例讲述了Node.js API详解之 readline模块用法。分享给大家供大家参考,具体如下:

Node.js API详解之 readline

readline 模块提供了一个接口,用于从可读流(如 process.stdin)读取数据,每次读取一行。
它可以通过以下方式使用:

const readline = require('readline');

readline 模块的基本用法:

const readline = require('readline');
const rl = readline.createInterface({
 input: process.stdin,
 output: process.stdout
});
rl.question('你认为 Node.js 中文网怎么样?', (answer) => {
 // 对答案进行处理
 console.log(`多谢你的反馈:${answer}`);
 rl.close();
});

注意:当调用该代码时,Node.js 程序不会终止,直到 readline.Interface 被关闭,因为接口在等待 input 流中要被接收的数据。

readline.createInterface(options)

说明:

readline.createInterface() 方法会创建一个新的 readline.Interface 实例。
options:
input:要监听的可读流。该选项是必需的。
output:要写入逐行读取数据的可写流。
completer:一个可选的函数,用于 Tab 自动补全。
terminal:如果 input 和 output 应被当作一个 TTY,且要写入 ANSI/VT100 转换的代码,则设为 true。 默认为实例化时在 output 流上检查 isTTY。
historySize:保留的历史行数的最大数量。 设为 0 可禁用历史记录。 该选项只有当 terminal 被用户或内部 output 设为 true 时才有意义,否则历史缓存机制不会被初始化。 默认为 30。
prompt:要使用的提示字符串。默认为 ‘> ‘。
crlfDelay:如果 \r 与 \n 之间的延迟超过 crlfDelay 毫秒,则 \r 和 \n 都会被当作换行分隔符。 默认为 100 毫秒。
removeHistoryDuplicates:设置为true时,将从历史列表中删除较旧的值。默认为 false。

demo:

const readline = require('readline');
const rl = readline.createInterface({
 input: process.stdin,
 output: process.stdout
});

Interface 类

说明:

readline.Interface 类的实例是使用 readline.createInterface() 方法构造的。
每个实例都关联一个 input 可读流和一个 output 可写流。
output 流用于为到达的用户输入打印提示,且从 input 流读取。

line 事件

说明:

每当 input 流接收到行结束符(\n、\r 或 \r\n)时触发 ‘line' 事件。
通常发生在用户按下 键或 键。
监听器函数被调用时会带上一个包含接收的那一行输入的字符串。

demo:

const readline = require('readline');
const rl = readline.createInterface({
 input: process.stdin,
 output: process.stdout
});
rl.on('line', (line) => {
 console.log(`接收到:${line}`);
});
// 1
// 接收到:1
// 2
// 接收到:2
// 3
// 接收到:3

rl.write(data[, key])

说明:

rl.write() 方法会把 data 或一个由 key 指定的按键序列写入到 output。
data:输出内容
key:
ctrl: 如果为 true 则表示 ctrl 键。
meta: 如果为 true 则表示 Meta 键。
shift: 如果为 true 则表示 Shift 键。
name: 一个按键的名称。
只有当 output 是一个 TTY 文本终端时,key 参数才被支持。
如果指定了 key,则 data 会被忽略。
当被调用时,如果 input 流已被暂停,则 rl.write() 会恢复 input 流。
如果 readline.Interface 被创建时 output 被设为 null 或 undefined,则 data 和 key 不会被写入。

demo:

const readline = require('readline');
const rl = readline.createInterface({
 input: process.stdin,
 output: process.stdout
});
rl.write('请输入姓名:');
rl.on('line', (input) => {
 //模拟 Ctrl+c 退出进程。
 rl.write('', {ctrl: true, name: 'c'});
});

rl.question(query, callback)

说明:

rl.question() 方法通过写入到 output 来展示 query,并等待用户提供到 input 的输入,
然后调用 callback 函数并传入提供的输入作为第一个参数。
query:一个在提示符之前、要写入 output 的叙述或询问。
callback:一个回调函数,它会被调用并带上用户响应 query 的输入。
当被调用时,如果 input 流已被暂停,则 rl.question() 会恢复 input 流。
如果 readline.Interface 被创建时 output 被设为 null 或 undefined,则 query 不会被写入。

demo:

const readline = require('readline');
const rl = readline.createInterface({
 input: process.stdin,
 output: process.stdout
});
rl.question('你是谁?', (answer) => {
 console.log('你好%s',answer);
});
// 你是谁?xiaoqiang
// 你好xiaoqiang

rl.close()

说明:

rl.close() 方法会关闭 readline.Interface 实例,且撤回对 input 和 output 流的控制。
但被调用时,'close' 事件会被触发。

demo:

const readline = require('readline');
const rl = readline.createInterface({
 input: process.stdin,
 output: process.stdout
});
rl.close();

close 事件

说明:

当以下之一发生时,触发 ‘close' 事件:
rl.close() 方法被调用,且 readline.Interface 实例已撤回对 input 流和 output 流的控制;
input 流接收到 ‘end' 事件;
input 流接收到表示结束传输的 ctrl-D;
input 流接收到表示 SIGINT 的 ctrl-C,且 readline.Interface 实例上没有注册 SIGINT 事件监听器。
监听器函数被调用时不传入任何参数。
当 ‘close' 事件被触发时,readline.Interface 实例应当被视为已结束。

demo:

const readline = require('readline');
const rl = readline.createInterface({
 input: process.stdin,
 output: process.stdout
});
rl.on('close', () => {
 console.log('已退出......')
});
rl.close();

SIGTSTP 事件

说明:

每当 input 流接收到一个 ctrl-Z 输入(通常被称为 SIGTSTP)时,触发 ‘SIGTSTP' 事件。
当 input 流接收到一个 SIGTSTP 时,如果没有注册 ‘SIGTSTP' 事件监听器,则 Node.js 进程会被发送到后台。
如果 input 流在进程被发送到后台之前被暂停,则 ‘pause' 和 SIGCONT 事件不会被触发。
监听器函数被调用时不传入任何参数。

demo:

const readline = require('readline');
const rl = readline.createInterface({
 input: process.stdin,
 output: process.stdout
});
rl.on('SIGTSTP', () => {
 console.log('退出请按Ctrl + c');
});

SIGINT 事件

说明:

每当 input 流接收到一个 ctrl-C 输入(通常被称为 SIGINT)时,触发 ‘SIGINT' 事件。
当 input 流接收到一个 SIGINT 时,如果没有注册 ‘SIGINT' 事件监听器,则 ‘pause' 事件会被触发。
监听器函数被调用时不传入任何参数。

demo:

const readline = require('readline');
const rl = readline.createInterface({
 input: process.stdin,
 output: process.stdout
});
rl.on('SIGINT', () => {
 console.log('已退出...');
 rl.close();
});

SIGCONT 事件

说明:

当一个 Node.js 进程使用 ctrl-Z(也就是 SIGTSTP)移入后台之后再使用 fg [ job_id ] 移回前台时,触发 ‘SIGCONT' 事件。
如果 input 流在 SIGTSTP 请求之前被暂停,则事件不会被触发。
监听器函数被调用时不传入任何参数。

demo:

const readline = require('readline');
const rl = readline.createInterface({
 input: process.stdin,
 output: process.stdout
});
rl.on('SIGCONT', () => {
 console.log('已唤起...');
});

rl.prompt([preserveCursor])

说明:

rl.prompt() 方法会在 output 流中新的一行写入 readline.Interface 实例配置后的 prompt,
用于为用户提供一个可供输入的新的位置。
preserveCursor:如果为 true,则阻止光标落点被设为 0。
当被调用时,如果 input 流已被暂停,则 rl.prompt() 会恢复 input 流。
如果 readline.Interface 被创建时 output 被设为 null 或 undefined,则提示不会被写入。

demo:

const readline = require('readline');
const rl = readline.createInterface({
 input: process.stdin,
 output: process.stdout
});
rl.question('你是谁?', (answer) => {
 console.log('你好%s',answer);
 rl.prompt();
});

rl.setPrompt(prompt)

说明:

rl.setPrompt() 方法用于设置每当 rl.prompt() 被调用时要被写入到 output 的提示。
prompt:提示内容

demo:

const readline = require('readline');
const rl = readline.createInterface({
 input: process.stdin,
 output: process.stdout
});
rl.setPrompt('用户输入:');
rl.on('line', (input) => {
 console.log(input);
 rl.prompt();
});

rl.pause()

说明:

rl.pause() 方法会暂停 input 流,且稍后需要时可被恢复。
调用 rl.pause() 不会立刻暂停其他事件(包括 ‘line')被 readline.Interface 实例触发。

demo:

const readline = require('readline');
const rl = readline.createInterface({
 input: process.stdin,
 output: process.stdout
});
rl.on('line', (input) => {
 console.log(input);
 rl.pause();
});

pause 事件

说明:

当以下之一发生时触发 ‘pause' 事件:
input 流被暂停。
input 流不是暂停的,且接收到 SIGCONT 事件。
监听器函数被调用时不传入任何参数。

demo:

const readline = require('readline');
const rl = readline.createInterface({
 input: process.stdin,
 output: process.stdout
});
rl.on('pause', () => {
 console.log('Readline 被暂停。');
});
rl.on('line', (input) => {
 console.log(input);
 rl.pause();
});

rl.resume()

说明:

如果 input 流已被暂停,则 rl.resume() 方法会恢复 input 流。

demo:

const readline = require('readline');
const rl = readline.createInterface({
 input: process.stdin,
 output: process.stdout
});
rl.on('line', (input) => {
 console.log(input);
 rl.pause();
 setTimeout( () => {
  rl.resume();
 },1000);
});

resume 事件

说明:

每当 input 流被恢复时触发 ‘resume' 事件。
监听器函数被调用时不传入任何参数

demo:

const readline = require('readline');
const rl = readline.createInterface({
 input: process.stdin,
 output: process.stdout
});
rl.on('resume', () => {
 console.log('Readline 被恢复。');
});
rl.on('line', (input) => {
 console.log(input);
 rl.pause();
 setTimeout( () => {
  rl.resume();
 },1000);
});

readline.cursorTo(stream, x, y)

说明:

readline.cursorTo() 方法会移动光标到给定的 TTY stream 中指定的位置。

demo:

const readline = require('readline');
readline.cursorTo(process.stdout, 10, 2);
const rl = readline.createInterface({
 input: process.stdin,
 output: process.stdout
});
rl.write('我在这!!!');

readline.moveCursor(stream, dx, dy)

说明:

readline.moveCursor() 方法会移动光标到给定的 TTY stream 中相对当前的位置。

demo:

const readline = require('readline');
readline.moveCursor(process.stdout, 10, 2);
const rl = readline.createInterface({
 input: process.stdin,
 output: process.stdout
});
rl.write('我在这!!!');
// lixiaoqiangdeMacBook-Pro:NodeApi xiaoqiang$ node app.js
//      我在这!!!

readline.clearScreenDown(stream)

说明:

eadline.clearScreenDown() 方法会从光标的当前位置向下清除给定的 TTY 流。

demo:

const readline = require('readline');
readline.clearScreenDown(process.stdout);
const rl = readline.createInterface({
 input: process.stdin,
 output: process.stdout
});
rl.write('我在这!!!');

readline.clearLine(stream, dir)

说明:

readline.clearLine() 方法会以 dir 指定的方向清除给定的 TTY 流的当前行。
dir:
-1 – 光标左边
1 – 光标右边
0 – 整行

demo:

const readline = require('readline');
const rl = readline.createInterface({
 input: process.stdin,
 output: process.stdout
});
rl.write('我在这!!!');
readline.clearLine(process.stdout, -1);

readline.emitKeypressEvents(stream[, interface])

说明:

readline.emitKeypressEvents() 方法使给定的可读流 stream 相应于接收到的输入触发 ‘keypress' 事件。
可选的 interface 指定了一个 readline.Interface 实例,用于当自动补全被禁用时检测到复制粘贴输入。
如果 stream 是一个 TTY,则它必须为原始模式。

demo:

const readline = require('readline');
const rl = readline.createInterface({
 input: process.stdin,
 output: process.stdout
});
rl.write('我在这!!!');
readline.emitKeypressEvents(process.stdin);

例子一:旋转进度

const readline = require('readline');
const rl = readline.createInterface({
 input: process.stdin,
 output: process.stdout
});
const imgArr = ['/', '-', '\\'];
let index = 0;
setInterval(() => {
 readline.clearLine(process.stdout, -1);
 readline.moveCursor(process.stdout, -1, 0);
 rl.write(imgArr[index]);
 if(index === 2){
 index=0;
 }else{
 index++;
 }
}, 200);

例子二:简单的命令行界面

const readline = require('readline');
const rl = readline.createInterface({
 input: process.stdin,
 output: process.stdout,
 prompt: '请输入> '
});
rl.prompt();
rl.on('line', (line) => {
 switch (line.trim()) {
  case 'hello':
   console.log('world!');
   break;
  default:
   console.log(`你输入的是:'${line.trim()}'`);
   break;
 }
 rl.prompt();
}).on('close', () => {
 console.log('再见!');
 process.exit(0);
});
// 请输入> 1
// 你输入的是:'1'
// 请输入> hello
// world!
// 请输入> 再见!

例子三:逐行地读取文件流

const readline = require('readline');
const fs = require('fs');
const rl = readline.createInterface({
 input: fs.createReadStream('stdout.log'),
 crlfDelay: Infinity
});
rl.on('line', (line) => {
 console.log(`文件的单行内容:${line}`);
});
// 文件的单行内容:1
// 文件的单行内容:2
// 文件的单行内容:3
// 文件的单行内容:4
// 文件的单行内容:5
// 文件的单行内容:6
// 文件的单行内容:7
// 文件的单行内容:8
// 文件的单行内容:9
// 文件的单行内容:0

希望本文所述对大家node.js程序设计有所帮助。

一句话新闻

一文看懂荣耀MagicBook Pro 16
荣耀猎人回归!七大亮点看懂不只是轻薄本,更是游戏本的MagicBook Pro 16.
人们对于笔记本电脑有一个固有印象:要么轻薄但性能一般,要么性能强劲但笨重臃肿。然而,今年荣耀新推出的MagicBook Pro 16刷新了人们的认知——发布会上,荣耀宣布猎人游戏本正式回归,称其继承了荣耀 HUNTER 基因,并自信地为其打出“轻薄本,更是游戏本”的口号。
众所周知,寻求轻薄本的用户普遍更看重便携性、外观造型、静谧性和打字办公等用机体验,而寻求游戏本的用户则普遍更看重硬件配置、性能释放等硬核指标。把两个看似难以相干的产品融合到一起,我们不禁对它产生了强烈的好奇:作为代表荣耀猎人游戏本的跨界新物种,它究竟做了哪些平衡以兼顾不同人群的各类需求呢?