require('readline')
模块提供了一个接口,用于从可读流(如 process.stdin
)读取数据,每次读取一行。 它可以通过以下方式使用:
const readline = require('readline');
readline模块的基本用法:
const readline = require('readline')
const rl = readline.createInterface({
input:process.stdin,
output:process.stdout
})
rl.question('你输入一句话试试?',(answer) => {
console.log('你说的话是:'+ anwser)
rl.close()
})
**注意:当调用这段代码时,Nodejs程序不会终止,直到readline.Interface
被关闭,因为接口在等待input
流中要被接收的数据
Interface 类
readline.Interface
类的实例是使用readline.createInterface()
方法构造的。每个实例都关联一个input
可读流和一个outpu
可写流。output
流用于为到达的用户输入打印提示,且从input流读取
'close'
事件
当一下之一发生是,触发‘close’事件
-
rl.close()
方法被调用,且readline.Interface
实例已经撤回对input
流和output
流的控制 -
input
流接收到end
事件 -
input
流接收到表示结束传输的<ctrl>-D
-
input
流接收到表示SIGINT
的<ctrl>-C
,且readline.Interface实例上没有注册SIGINT
事件监听器
监听器函数被调用时不传入任何参数
当close
事件被触发时,readline实例会被结束
line
事件
每当input
流接收到接收行结束符(\n
,\r
或\r\n
时触发line
事件。通常发生在用户按下<Enter> 键或 <Return> 键。)
rl.on('line', (input) => {
console.log(`接收到:${input}`);
});
pause
事件
当以下之一发生时触发 'pause' 事件:
input
流被暂停。
input
流不是暂停的,且接收到SIGCONT
事件。
监听器函数被调用时不传入任何参数。
例子:
rl.on('pause', () => {
console.log('Readline 被暂停。');
});
resume
事件
每当input
流被恢复是触发resume
事件
rl.on('resume', () => {
console.log('Readline 被恢复。');
});
'SIGCONT'
事件
当一个 Node.js 进程使用 <ctrl>-Z
(也就是 SIGTSTP
)移入后台之后再使用 fg(1p)
移回前台时,触发 'SIGCONT'
事件。
如果 input
流在 SIGTSTP
请求之前被暂停,则事件不会被触发。
监听器函数被调用时不传入任何参数。
rl.on('SIGCONT', () => {
// `prompt` 会自动恢复流
rl.prompt();
});
'SIGINT'
事件
每当 input 流接收到一个 <ctrl>-C 输入(通常被称为 SIGINT)时,触发 'SIGINT' 事件。 当 input 流接收到一个 SIGINT 时,如果没有注册 'SIGINT' 事件监听器,则 'pause' 事件会被触发。
监听器函数被调用时不传入任何参数。
'SIGTSTP'
事件
每当 input
流接收到一个 <ctrl>-Z
输入(通常被称为 SIGTSTP
)时,触发 'SIGTSTP'
事件。 当 input
流接收到一个 SIGTSTP
时,如果没有注册 'SIGTSTP'
事件监听器,则 Node.js 进程会被发送到后台。
当程序使用 fg(1p)
恢复时'pause'
和 SIGCONT
事件会被触发。 这可被用来恢复 input
流。
如果 input
流在进程被发送到后台之前被暂停,则 'pause'
和 SIGCONT
事件不会被触发。
监听器函数被调用时不传入任何参数。
rl.on('SIGTSTP', () => {
// 这会重写 SIGTSTP,且防止程序进入后台。
console.log('捕获 SIGTSTP。');
});
rl.close()
关闭readline.Interface实例,且撤回对input和output流的控制。被调用时,‘close’事件会被触发
rl.pause()
rl.pause()
方法会暂停input流,且稍后需要时刻被恢复
rl.prompt([preserveCursor])
(下一行)
- preserveCursor如果为true,则阻止光标落点被设置为0
rl.prompt()
方法会在output流中新的一行写入readline.Interface实例配置后的prompt
,用于为用户提供一个可供输入的新的位置当被调用时,如果input
流被暂停,则rl.prompt
会恢复input流
如果readline.Interface
被创建是output被设为null或者undefined,则提示不会被写入。
rl.question(query,callback)
-
query
在展示之前,需要提示给用户的语言 -
callback
一个回调函数,它会被调用并带上用户输入的东西
rl.question()
方法通过写入到output来展示query,并等待用户提供到了input输入,然后调用callback函数并传提供的输入作为第一个参数
注意:传入的 rl.question() 的 callback 函数不遵循接受一个 Error 对象或 null 作为第一个参数的标准模式。 callback 被调用时只带上提供的答案作为唯一的参数。
rl.resume()
如果 input 流已被暂停,则 rl.resume() 方法会恢复 input 流。
rl.setPrompt(prompt)
rl.setPrompt() 方法用于设置每当 rl.prompt() 被调用时要被写入到 output 的提示。
rl.write(data[, key])
提前写入到output流中
readline.clearLine(stream, dir)
stream
<stream.Writable>-
dir
<number>-
-1
- 光标左边 -
1
- 光标右边 -
0
- 整行
-
会以dir指定的方向清除给定的TTY流的当前行
readline.clearScreenDown(stream)
readline.clearScreenDown()
方法会从光标的当前位置向下清除给定的 TTY 流。
readline.createInterface(options)
-
options
<Object>-
input
<stream.Readable> 要监听的可读流。该选项是必需的。 -
output
<stream.Writable> 要写入逐行读取数据的可写流。 -
completer
<Function> 一个可选的函数,用于 Tab 自动补全。 -
terminal
<boolean> 如果input
和output
应被当作一个 TTY,且要写入 ANSI/VT100 转换的代码,则设为true
。 默认为实例化时在output
流上检查isTTY
。 -
historySize
<number> 保留的历史行数的最大数量。 设为0
可禁用历史记录。 该选项只有当terminal
被用户或内部output
设为true
时才有意义,否则历史缓存机制不会被初始化。 默认为30
。 -
prompt
- 要使用的提示字符串。默认为'> '
。 -
crlfDelay
<number> 如果\r
与\n
之间的延迟超过crlfDelay
毫秒,则\r
和\n
都会被当作换行分隔符。crlfDelay
强制设置为不少于100
. 可以设置为Infinity
, 这种情况下,\r
跟着\n
会被视为单个新行(也许对带有\r\n
分隔符的[reading files][]
来说是非常合理的)。 默认为100
毫秒。 -
removeHistoryDuplicates
<boolean> 如果为true
, 当新输入行与历史列表中的某行相同时, 那么移除旧有的行。 默认为false
。
-
readline.createInterface()
方法会创建一个新的 readline.Interface
实例。
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
一旦 readline.Interface 实例被创建,最常见的用法是监听 'line' 事件:
rl.on('line', (line) => {
console.log(`接收到:${line}`);
});
completer 函数的使用
completer 函数会获取用户输入的当前行作为参数,并返回一个包含以下两个条目的数组:
- 一个包含匹配补全输入的数组。
- 用于匹配的子字符串。
readline.cursorTo(stream, x, y)
-
stream
<stream.Writable> -
x
<number> -
y
<number>
readline.cursorTo()
方法会移动光标到给定的 TTY stream
中指定的位置。
readline.emitKeypressEvents(stream[, interface])
readline.emitKeypressEvents()
方法使给定的可读流 stream
响应于接收到的输入触发 'keypress'
事件。
readline.moveCursor(stream, dx, dy)
-
stream
<stream.Writable> -
dx
<number> -
dy
<number>
readline.moveCursor()
方法会移动光标到给定的 TTY stream
中相对当前的位置。
一个简单命令行交互的例子:
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);
})
逐行地读取文件流
例子,从一个文件系统可读流中每次一行地消耗输入:
const readline = require('readline')
const fs = require('fs')
const rl = readline.createInterface({
input: fs.createReadStream('./foo.js'),
crlfDelay: Infinity
})
rl.on('line', line => {
console.log(`文件的单行内容:${line}`);
})