- assert 断言
- async_hooks 异步钩子
- async_hooks/context 异步上下文
- buffer 缓冲区
- C++插件
- C/C++插件(使用 Node-API)
- C++嵌入器
- child_process 子进程
- cluster 集群
- CLI 命令行
- console 控制台
- Corepack 核心包
- crypto 加密
- crypto/webcrypto 网络加密
- debugger 调试器
- deprecation 弃用
- dgram 数据报
- diagnostics_channel 诊断通道
- dns 域名服务器
- domain 域
- Error 错误
- events 事件触发器
- fs 文件系统
- global 全局变量
- http 超文本传输协议
- http2 超文本传输协议 2.0
- https 安全超文本传输协议
- inspector 检查器
- Intl 国际化
- module 模块
- module/cjs CommonJS 模块
- module/esm ECMAScript 模块
- module/package 包模块
- net 网络
- os 操作系统
- path 路径
- perf_hooks 性能钩子
- permission 权限
- process 进程
- punycode 域名代码
- querystring 查询字符串
- readline 逐行读取
- repl 交互式解释器
- report 诊断报告
- stream 流
- stream/web 网络流
- string_decoder 字符串解码器
- test 测试
- timers 定时器
- tls 安全传输层
- trace_events 跟踪事件
- tty 终端
- url 网址
- util 实用工具
- v8 引擎
- vm 虚拟机
- wasi 网络汇编系统接口
- worker_threads 工作线程
- zlib 压缩
Node.js v16.20.2 文档
- Node.js v16.20.2
-
目录
- 逐行读取
- 类:
接口- 事件:
'close' - 事件:
'line' - 事件:
'history' - 事件:
'pause' - 事件:
'resume' - 事件:
'SIGCONT' - 事件:
'SIGINT' - 事件:
'SIGTSTP' rl.close()rl.pause()rl.prompt([preserveCursor])rl.question(query[, options], callback)rl.resume()rl.setPrompt(prompt)rl.getPrompt()rl.write(data[, key])rl[Symbol.asyncIterator]()rl.linerl.cursorrl.getCursorPos()
- 事件:
readline.clearLine(stream, dir[, callback])readline.clearScreenDown(stream[, callback])readline.createInterface(options)readline.cursorTo(stream, x[, y][, callback])readline.emitKeypressEvents(stream[, interface])readline.moveCursor(stream, dx, dy[, callback])- 示例:Tiny CLI
- 示例:逐行读取文件流
- TTY 键绑定
- 类:
- 逐行读取
-
导航
- assert 断言
- async_hooks 异步钩子
- async_hooks/context 异步上下文
- buffer 缓冲区
- C++插件
- C/C++插件(使用 Node-API)
- C++嵌入器
- child_process 子进程
- cluster 集群
- CLI 命令行
- console 控制台
- Corepack 核心包
- crypto 加密
- crypto/webcrypto 网络加密
- debugger 调试器
- deprecation 弃用
- dgram 数据报
- diagnostics_channel 诊断通道
- dns 域名服务器
- domain 域
- Error 错误
- events 事件触发器
- fs 文件系统
- global 全局变量
- http 超文本传输协议
- http2 超文本传输协议 2.0
- https 安全超文本传输协议
- inspector 检查器
- Intl 国际化
- module 模块
- module/cjs CommonJS 模块
- module/esm ECMAScript 模块
- module/package 包模块
- net 网络
- os 操作系统
- path 路径
- perf_hooks 性能钩子
- permission 权限
- process 进程
- punycode 域名代码
- querystring 查询字符串
- readline 逐行读取
- repl 交互式解释器
- report 诊断报告
- stream 流
- stream/web 网络流
- string_decoder 字符串解码器
- test 测试
- timers 定时器
- tls 安全传输层
- trace_events 跟踪事件
- tty 终端
- url 网址
- util 实用工具
- v8 引擎
- vm 虚拟机
- wasi 网络汇编系统接口
- worker_threads 工作线程
- zlib 压缩
- 其他版本
逐行读取#>
【Readline】
源代码: lib/readline.js
node:readline 模块提供了一个接口,用于一次从 可读的 流(例如 process.stdin)读取一行数据。
可以通过以下方式访问:
【The node:readline module provides an interface for reading data from a
Readable stream (such as process.stdin) one line at a time.
It can be accessed using:】
const readline = require('node:readline');
下面的简单示例说明了 node:readline 模块的基本用法。
【The following simple example illustrates the basic use of the node:readline
module.】
const readline = require('node:readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.question('What do you think of Node.js? ', (answer) => {
// TODO: Log the answer in a database
console.log(`Thank you for your valuable feedback: ${answer}`);
rl.close();
});
一旦调用此代码,Node.js 应用将不会终止,直到 readline.Interface 被关闭,因为该接口会等待在 input 流上接收数据。
【Once this code is invoked, the Node.js application will not terminate until the
readline.Interface is closed because the interface waits for data to be
received on the input stream.】
类:接口#>
【Class: Interface】
- 继承: <EventEmitter>
readline.Interface 类的实例是通过 readline.createInterface() 方法创建的。每个实例都关联一个 input 可读的 流和一个 output 可写 流。output 流用于打印供用户输入的提示,这些输入会通过 input 流到达并从中读取。
【Instances of the readline.Interface class are constructed using the
readline.createInterface() method. Every instance is associated with a
single input Readable stream and a single output Writable stream.
The output stream is used to print prompts for user input that arrives on,
and is read from, the input stream.】
事件:'close'#>
【Event: 'close'】
当发生以下情况之一时,会触发 'close' 事件:
【The 'close' event is emitted when one of the following occur:】
- 调用了
rl.close()方法,readline.Interface实例已放弃对input和output流的控制; input流接收到'end'事件;input流接收到 Ctrl+D 来表示传输结束 (EOT);input流接收到 Ctrl+C 来表示SIGINT,并且在readline.Interface实例上没有注册'SIGINT'事件监听器。
调用监听器函数时不传入任何参数。
【The listener function is called without passing any arguments.】
readline.Interface 实例在 'close' 事件被触发后就结束了。
【The readline.Interface instance is finished once the 'close' event is
emitted.】
事件:'line'#>
【Event: 'line'】
'line' 事件会在 input 流接收到换行输入(\n、\r 或 \r\n)时触发。这通常发生在用户按下 回车 或 Return键时。
如果从流中读取了新数据,并且该流在没有最终换行符的情况下结束,则也会触发 'line' 事件。
【The 'line' event is also emitted if new data has been read from a stream and
that stream ends without a final end-of-line marker.】
监听函数会被调用,并传入一个包含收到的单行输入的字符串。
【The listener function is called with a string containing the single line of received input.】
rl.on('line', (input) => {
console.log(`Received: ${input}`);
});
事件:'history'#>
【Event: 'history'】
每当历史数组发生变化时,都会触发 'history' 事件。
【The 'history' event is emitted whenever the history array has changed.】
监听器函数会被调用,并传入一个包含历史记录数组的数组。它会反映所有的更改、添加的行以及由于 historySize 和 removeHistoryDuplicates 导致的删除的行。
【The listener function is called with an array containing the history array.
It will reflect all changes, added lines and removed lines due to
historySize and removeHistoryDuplicates.】
主要目的是允许监听器保存历史记录。监听器也可以更改历史对象。这可能有助于防止某些行被添加到历史记录中,例如密码。
【The primary purpose is to allow a listener to persist the history. It is also possible for the listener to change the history object. This could be useful to prevent certain lines to be added to the history, like a password.】
rl.on('history', (history) => {
console.log(`Received: ${history}`);
});
事件:'pause'#>
【Event: 'pause'】
当发生以下情况之一时,会触发 'pause' 事件:
【The 'pause' event is emitted when one of the following occur:】
调用监听器函数时不传入任何参数。
【The listener function is called without passing any arguments.】
rl.on('pause', () => {
console.log('Readline paused.');
});
事件:'resume'#>
【Event: 'resume'】
每当 input 流恢复时,都会触发 'resume' 事件。
【The 'resume' event is emitted whenever the input stream is resumed.】
调用监听器函数时不传入任何参数。
【The listener function is called without passing any arguments.】
rl.on('resume', () => {
console.log('Readline resumed.');
});
事件:'SIGCONT'#>
【Event: 'SIGCONT'】
'SIGCONT' 事件会在先前使用 Ctrl+Z (即 SIGTSTP) 将 Node.js 进程移到后台后,再通过 fg(1p) 将其重新带回前台时触发。
如果在 SIGTSTP 请求之前 input 流已被暂停,则不会触发此事件。
【If the input stream was paused before the SIGTSTP request, this event will
not be emitted.】
调用监听器函数时不传入任何参数。
【The listener function is invoked without passing any arguments.】
rl.on('SIGCONT', () => {
// `prompt` will automatically resume the stream
rl.prompt();
});
'SIGCONT' 事件在 Windows 上不受支持。
【The 'SIGCONT' event is not supported on Windows.】
事件:'SIGINT'#>
【Event: 'SIGINT'】
每当 input 流收到通常称为 SIGINT 的 Ctrl+C 输入时,就会触发 'SIGINT' 事件。如果在 input 流收到 SIGINT 时没有注册 'SIGINT' 事件监听器,将会触发 'pause' 事件。
调用监听器函数时不传入任何参数。
【The listener function is invoked without passing any arguments.】
rl.on('SIGINT', () => {
rl.question('Are you sure you want to exit? ', (answer) => {
if (answer.match(/^y(es)?$/i)) rl.pause();
});
});
事件:'SIGTSTP'#>
【Event: 'SIGTSTP'】
当 input 流接收到 a Ctrl+Z 输入时,会触发 'SIGTSTP' 事件,这通常被称为 SIGTSTP。如果在 input 流接收到 SIGTSTP 时没有注册 'SIGTSTP' 事件监听器,Node.js 进程将会被送到后台运行。
当使用 fg(1p) 恢复程序时,将会触发 'pause' 和 'SIGCONT' 事件。这些事件可以用于恢复 input 流。
【When the program is resumed using fg(1p), the 'pause' and 'SIGCONT' events
will be emitted. These can be used to resume the input stream.】
如果在将进程置于后台之前 input 已被暂停,则不会触发 'pause' 和 'SIGCONT' 事件。
【The 'pause' and 'SIGCONT' events will not be emitted if the input was
paused before the process was sent to the background.】
调用监听器函数时不传入任何参数。
【The listener function is invoked without passing any arguments.】
rl.on('SIGTSTP', () => {
// This will override SIGTSTP and prevent the program from going to the
// background.
console.log('Caught SIGTSTP.');
});
'SIGTSTP' 事件在 Windows 上不支持。
【The 'SIGTSTP' event is not supported on Windows.】
rl.close()#>
rl.close() 方法会关闭 readline.Interface 实例,并释放对 input 和 output 流的控制。当调用该方法时,将触发 'close' 事件。
【The rl.close() method closes the readline.Interface instance and
relinquishes control over the input and output streams. When called,
the 'close' event will be emitted.】
调用 rl.close() 并不会立即停止 readline.Interface 实例发出的其他事件(包括 'line')。
【Calling rl.close() does not immediately stop other events (including 'line')
from being emitted by the readline.Interface instance.】
rl.pause()#>
rl.pause() 方法会暂停 input 流,以便在必要时可以稍后恢复。
【The rl.pause() method pauses the input stream, allowing it to be resumed
later if necessary.】
调用 rl.pause() 并不会立即暂停 readline.Interface 实例发出的其他事件(包括 'line')。
【Calling rl.pause() does not immediately pause other events (including
'line') from being emitted by the readline.Interface instance.】
rl.prompt([preserveCursor])#>
preserveCursor<boolean> 如果为true,则防止光标位置被重置为0。
rl.prompt() 方法会将 readline.Interface 实例所配置的 prompt 写入 output 的新一行,以便为用户提供一个新的位置来输入内容。
【The rl.prompt() method writes the readline.Interface instances configured
prompt to a new line in output in order to provide a user with a new
location at which to provide input.】
当被调用时,rl.prompt() 将会恢复已暂停的 input 流。
【When called, rl.prompt() will resume the input stream if it has been
paused.】
如果使用 output 设置为 null 或 undefined 创建了 readline.Interface,则不会显示提示符。
【If the readline.Interface was created with output set to null or
undefined the prompt is not written.】
rl.question(query[, options], callback)#>
query<string> 要写入output的语句或查询,会被添加到提示的前面。options<Object>signal<AbortSignal> 可选,允许使用AbortController取消question()。
callback<Function> 回调函数,当用户对query做出输入时会被调用。
rl.question() 方法通过将 query 写入 output 来显示问题,等待用户在 input 上提供输入,然后调用 callback 函数,将提供的输入作为第一个参数传递给它。
【The rl.question() method displays the query by writing it to the output,
waits for user input to be provided on input, then invokes the callback
function passing the provided input as the first argument.】
当被调用时,如果 input 流已被暂停,rl.question() 将会恢复该流。
【When called, rl.question() will resume the input stream if it has been
paused.】
如果使用 output 设置为 null 或 undefined 创建了 readline.Interface,则不会写入 query。
【If the readline.Interface was created with output set to null or
undefined the query is not written.】
传递给 rl.question() 的 callback 函数不遵循通常接受 Error 对象或 null 作为第一个参数的模式。callback 会被调用,并将提供的答案作为唯一参数传入。
【The callback function passed to rl.question() does not follow the typical
pattern of accepting an Error object or null as the first argument.
The callback is called with the provided answer as the only argument.】
用法示例:
【Example usage:】
rl.question('What is your favorite food? ', (answer) => {
console.log(`Oh, so your favorite food is ${answer}`);
});
使用 AbortController 来取消一个问题。
【Using an AbortController to cancel a question.】
const ac = new AbortController();
const signal = ac.signal;
rl.question('What is your favorite food? ', { signal }, (answer) => {
console.log(`Oh, so your favorite food is ${answer}`);
});
signal.addEventListener('abort', () => {
console.log('The food question timed out');
}, { once: true });
setTimeout(() => ac.abort(), 10000);
如果以它被 util.promisify() 处理后的版本调用此方法,它将返回一个 Promise,并在得到答案时完成。如果使用 AbortController 取消问题,它将以 AbortError 拒绝。
【If this method is invoked as it's util.promisify()ed version, it returns a
Promise that fulfills with the answer. If the question is canceled using
an AbortController it will reject with an AbortError.】
const util = require('node:util');
const question = util.promisify(rl.question).bind(rl);
async function questionExample() {
try {
const answer = await question('What is you favorite food? ');
console.log(`Oh, so your favorite food is ${answer}`);
} catch (err) {
console.error('Question rejected', err);
}
}
questionExample();
rl.resume()#>
rl.resume() 方法会在 input 流被暂停后恢复它。
【The rl.resume() method resumes the input stream if it has been paused.】
rl.setPrompt(prompt)#>
提示<string>
rl.setPrompt() 方法设置提示符,每当调用 rl.prompt() 时,该提示符将被写入 output。
【The rl.setPrompt() method sets the prompt that will be written to output
whenever rl.prompt() is called.】
rl.getPrompt()#>
- 返回: <string> 当前的提示字符串
rl.getPrompt() 方法返回 rl.prompt() 当前使用的提示符。
【The rl.getPrompt() method returns the current prompt used by rl.prompt().】
rl.write(data[, key])#>
data<string>key<Object>ctrl<boolean>true表示 Ctrl 键。
meta<boolean>true表示 Meta 键。shift<boolean>true表示 Shift 键。name<string> 键的名称。
rl.write() 方法将把 data 或由 key 标识的按键序列写入 output。只有当 output 是 文字电话 文本终端时,才支持 key 参数。有关按键组合的列表,请参见 TTY 键绑定。
【The rl.write() method will write either data or a key sequence identified
by key to the output. The key argument is supported only if output is
a TTY text terminal. See TTY keybindings for a list of key
combinations.】
如果指定了 key,data 将被忽略。
【If key is specified, data is ignored.】
当被调用时,rl.write() 将会恢复已暂停的 input 流。
【When called, rl.write() will resume the input stream if it has been
paused.】
如果 readline.Interface 是在将 output 设置为 null 或 undefined 的情况下创建的,则 data 和 key 不会被写入。
【If the readline.Interface was created with output set to null or
undefined the data and key are not written.】
rl.write('Delete this!');
// Simulate Ctrl+U to delete the line written previously
rl.write(null, { ctrl: true, name: 'u' });
rl.write() 方法会将数据写入 readline Interface 的 input,就好像是用户提供的一样。
【The rl.write() method will write the data to the readline Interface's
input as if it were provided by the user.】
rl[Symbol.asyncIterator]()#>
- 返回: <AsyncIterator>
创建一个 AsyncIterator 对象,该对象可以将输入流中的每一行作为字符串进行迭代。此方法允许通过 for await...of 循环异步迭代 readline.Interface 对象。
【Create an AsyncIterator object that iterates through each line in the input
stream as a string. This method allows asynchronous iteration of
readline.Interface objects through for await...of loops.】
输入流中的错误不会被转发。
【Errors in the input stream are not forwarded.】
如果循环通过 break、throw 或 return 终止,rl.close() 将被调用。换句话说,对 readline.Interface 的迭代将始终完全消耗输入流。
【If the loop is terminated with break, throw, or return,
rl.close() will be called. In other words, iterating over a
readline.Interface will always consume the input stream fully.】
性能不如传统的 'line' 事件 API。对于对性能敏感的应用,请使用 'line'。
【Performance is not on par with the traditional 'line' event API. Use 'line'
instead for performance-sensitive applications.】
async function processLineByLine() {
const rl = readline.createInterface({
// ...
});
for await (const line of rl) {
// Each line in the readline input will be successively available here as
// `line`.
}
}
readline.createInterface() 一旦被调用就会开始消耗输入流。在创建接口和异步迭代之间进行异步操作可能会导致遗漏行。
rl.line#>
节点正在处理的当前输入数据。
【The current input data being processed by node.】
当从 TTY 流收集输入以在 line 事件触发之前获取当前已处理的值时,可以使用此方法。一旦 line 事件被触发,该属性将为空字符串。
【This can be used when collecting input from a TTY stream to retrieve the
current value that has been processed thus far, prior to the line event
being emitted. Once the line event has been emitted, this property will
be an empty string.】
请注意,如果不同时控制 rl.cursor,在实例运行时修改该值可能会产生意想不到的后果。
【Be aware that modifying the value during the instance runtime may have
unintended consequences if rl.cursor is not also controlled.】
如果不使用 TTY 流作为输入,请使用 'line' 事件。
一个可能的用例如下:
【One possible use case would be as follows:】
const values = ['lorem ipsum', 'dolor sit amet'];
const rl = readline.createInterface(process.stdin);
const showResults = debounce(() => {
console.log(
'\n',
values.filter((val) => val.startsWith(rl.line)).join(' ')
);
}, 300);
process.stdin.on('keypress', (c, k) => {
showResults();
});
rl.cursor#>
光标位置相对于 rl.line 的位置。
【The cursor position relative to rl.line.】
当从 TTY 流读取输入时,这将跟踪当前光标在输入字符串中的位置。光标的位置决定了在处理输入时输入字符串中将被修改的部分,以及终端光标将显示的列位置。
【This will track where the current cursor lands in the input string, when reading input from a TTY stream. The position of cursor determines the portion of the input string that will be modified as input is processed, as well as the column where the terminal caret will be rendered.】
rl.getCursorPos()#>
返回光标相对于输入提示符 + 字符串的实际位置。计算中包括长输入(换行)字符串以及多行提示符。
【Returns the real position of the cursor in relation to the input prompt + string. Long input (wrapping) strings, as well as multiple line prompts are included in the calculations.】
readline.clearLine(stream, dir[, callback])#>
stream<stream.Writable>dir<number>-1:从光标向左1:从光标向右0:整行
callback<Function> 操作完成后调用。- 返回值:<boolean> 如果
stream希望调用代码等待'drain'事件触发后再继续写入额外数据,则返回false;否则返回true。
readline.clearLine() 方法清除给定 文字电话 流中当前行的内容,清除的方向由 dir 指定。
【The readline.clearLine() method clears current line of given TTY stream
in a specified direction identified by dir.】
readline.clearScreenDown(stream[, callback])#>
stream<stream.Writable>callback<Function> 操作完成后调用。- 返回值: <boolean> 如果
stream希望调用代码在继续写入更多数据之前等待'drain'事件触发,则返回false;否则返回true。
readline.clearScreenDown() 方法会清除从当前光标位置向下的指定 文字电话 流内容。
【The readline.clearScreenDown() method clears the given TTY stream from
the current position of the cursor down.】
readline.createInterface(options)#>
options<Object>input<stream.Readable> 要监听的 可读的 流。此选项为_必填_。output<stream.Writable> 写入 readline 数据的 可写 流。- 'completer' <Function> 用于制表表自动补全的可选函数。
terminal<boolean>true如果input和output流应该被当作 TTY 处理,并向其写入 ANSI/VT100 转义代码。 默认值: 在实例化时检查output流的isTTY。history<string[]> 初始历史记录行列表。只有当用户或内部output检查将terminal设置为true时,此选项才有意义,否则历史缓存机制根本不会被初始化。默认值:[]。historySize<number> 保留的历史行的最大数量。要禁用历史记录,将此值设置为0。只有当用户或内部的output检查将terminal设置为true时,此选项才有意义,否则历史缓存机制根本不会初始化。 默认值:30。removeHistoryDuplicates<boolean> 如果为true,当向历史记录列表添加新输入行时,如果与旧的输入重复,则会从列表中删除旧的那一行。默认值:false。prompt<string> 要使用的提示字符串。默认值:'> '。crlfDelay<number> 如果和之间的延迟超过crlfDelay毫秒,则和都会被视为单独的行结束输入。crlfDelay将被强制转换为不小于100的数字。它可以设置为Infinity,在这种情况下,后跟将始终被视为单个换行符(对于使用行分隔符的 读取文件 来说,这可能是合理的)。默认值:100。escapeCodeTimeout<number>readline等待字符的时间(在毫秒中,当读取一个模糊的按键序列时,此字符既可以用当前读取的输入形成一个完整的按键序列,也可以接受额外输入以完成一个更长的按键序列)。 默认值:500.tabSize<integer> 制表符等于的空格数(最少为 1)。 默认值:8。signal<AbortSignal> 允许使用 AbortSignal 关闭接口。 中止该信号将会在内部调用接口的close方法。
- 返回: <readline.Interface>
readline.createInterface() 方法创建一个新的 readline.Interface 实例。
【The readline.createInterface() method creates a new readline.Interface
instance.】
const readline = require('node:readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
一旦创建了 readline.Interface 实例,最常见的情况是监听 'line' 事件:
【Once the readline.Interface instance is created, the most common case is to
listen for the 'line' event:】
rl.on('line', (line) => {
console.log(`Received: ${line}`);
});
如果此实例的 terminal 为 true,那么 output 流如果定义了 output.columns 属性并在列数发生变化时或变化时触发 output 的 'resize' 事件,将获得最佳兼容性(process.stdout 在作为 TTY 时会自动执行此操作)。
【If terminal is true for this instance then the output stream will get
the best compatibility if it defines an output.columns property and emits
a 'resize' event on the output if or when the columns ever change
(process.stdout does this automatically when it is a TTY).】
在使用 stdin 作为输入创建 readline.Interface 时,程序不会终止,直到收到 文件结束字符。若想在不等待用户输入的情况下退出,请调用 process.stdin.unref()。
【When creating a readline.Interface using stdin as input, the program
will not terminate until it receives an EOF character. To exit without
waiting for user input, call process.stdin.unref().】
completer 函数的使用#>
【Use of the completer function】
completer 函数以用户输入的当前行作为参数,并返回一个包含 2 个条目的 数组:
【The completer function takes the current line entered by the user
as an argument, and returns an Array with 2 entries:】
- 一个包含匹配条目的
Array。 - 用于匹配的子字符串。
例如:[[substr1, substr2, ...], originalsubstring]。
【For instance: [[substr1, substr2, ...], originalsubstring].】
function completer(line) {
const completions = '.help .error .exit .quit .q'.split(' ');
const hits = completions.filter((c) => c.startsWith(line));
// Show all completions if none found
return [hits.length ? hits : completions, line];
}
completer 函数如果接受两个参数,可以异步调用:
【The completer function can be called asynchronously if it accepts two
arguments:】
function completer(linePartial, callback) {
callback(null, [['123'], linePartial]);
}
readline.cursorTo(stream, x[, y][, callback])#>
stream<stream.Writable>x<number>y<number>callback<Function> 在操作完成后调用。- 返回值: <boolean> 如果
stream希望调用代码在继续写入额外数据之前等待'drain'事件触发,则返回false;否则返回true。
readline.cursorTo() 方法将光标移动到给定 文字电话 stream 中的指定位置。
【The readline.cursorTo() method moves cursor to the specified position in a
given TTY stream.】
readline.emitKeypressEvents(stream[, interface])#>
stream<stream.Readable>interface<readline.Interface>
readline.emitKeypressEvents() 方法使给定的 可读的 流开始发出对应于接收到的输入的 'keypress' 事件。
【The readline.emitKeypressEvents() method causes the given Readable
stream to begin emitting 'keypress' events corresponding to received input.】
可选地,interface 指定一个 readline.Interface 实例,当检测到粘贴输入时将禁用自动补全。
【Optionally, interface specifies a readline.Interface instance for which
autocompletion is disabled when copy-pasted input is detected.】
如果 stream 是 文字电话,那么它必须处于原始模式。
【If the stream is a TTY, then it must be in raw mode.】
如果 input 是终端,任何 readline 实例在其 input 上都会自动调用此方法。关闭 readline 实例不会阻止 input 发出 'keypress' 事件。
【This is automatically called by any readline instance on its input if the
input is a terminal. Closing the readline instance does not stop
the input from emitting 'keypress' events.】
readline.emitKeypressEvents(process.stdin);
if (process.stdin.isTTY)
process.stdin.setRawMode(true);
readline.moveCursor(stream, dx, dy[, callback])#>
stream<stream.Writable>dx<number>dy<number>callback<Function> 操作完成后调用。- 返回值: <boolean> 如果
stream希望调用代码在继续写入额外数据之前等待'drain'事件触发,则返回false;否则返回true。
readline.moveCursor() 方法将光标相对于其在指定 文字电话 stream 中的当前位置移动。
【The readline.moveCursor() method moves the cursor relative to its current
position in a given TTY stream.】
示例:Tiny CLI#>
【Example: Tiny CLI】
以下示例演示了如何使用 readline.Interface 类来实现一个小型命令行接口:
【The following example illustrates the use of readline.Interface class to
implement a small command-line interface:】
const readline = require('node:readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
prompt: 'OHAI> '
});
rl.prompt();
rl.on('line', (line) => {
switch (line.trim()) {
case 'hello':
console.log('world!');
break;
default:
console.log(`Say what? I might have heard '${line.trim()}'`);
break;
}
rl.prompt();
}).on('close', () => {
console.log('Have a great day!');
process.exit(0);
});
示例:逐行读取文件流#>
【Example: Read file stream line-by-Line】
node:readline 的一个常见用例是一次读取输入文件的一行。最简单的方法是利用 fs.ReadStream API 以及 for await...of 循环:
【A common use case for node:readline is to consume an input file one line at a
time. The easiest way to do so is leveraging the fs.ReadStream API as
well as a for await...of loop:】
const fs = require('node:fs');
const readline = require('node:readline');
async function processLineByLine() {
const fileStream = fs.createReadStream('input.txt');
const rl = readline.createInterface({
input: fileStream,
crlfDelay: Infinity
});
// Note: we use the crlfDelay option to recognize all instances of CR LF
// ('\r\n') in input.txt as a single line break.
for await (const line of rl) {
// Each line in input.txt will be successively available here as `line`.
console.log(`Line from file: ${line}`);
}
}
processLineByLine();
或者,可以使用 'line' 事件:
【Alternatively, one could use the 'line' event:】
const fs = require('node:fs');
const readline = require('node:readline');
const rl = readline.createInterface({
input: fs.createReadStream('sample.txt'),
crlfDelay: Infinity
});
rl.on('line', (line) => {
console.log(`Line from file: ${line}`);
});
目前,for await...of 循环可能会稍慢一些。如果 async / await 的流程和速度都很重要,可以采用混合方法:
【Currently, for await...of loop can be a bit slower. If async / await
flow and speed are both essential, a mixed approach can be applied:】
const { once } = require('node:events');
const { createReadStream } = require('node:fs');
const { createInterface } = require('node:readline');
(async function processLineByLine() {
try {
const rl = createInterface({
input: createReadStream('big-file.txt'),
crlfDelay: Infinity
});
rl.on('line', (line) => {
// Process the line.
});
await once(rl, 'close');
console.log('File processed.');
} catch (err) {
console.error(err);
}
})();
TTY 键绑定#>
【TTY keybindings】
| Keybindings | Description | Notes |
|---|---|---|
| Ctrl+Shift+Backspace | Delete line left | Doesn't work on Linux, Mac and Windows |
| Ctrl+Shift+Delete | Delete line right | Doesn't work on Mac |
| Ctrl+C | Emit SIGINT or close the readline instance |
|
| Ctrl+H | Delete left | |
| Ctrl+D | Delete right or close the readline instance in case the current line is empty / EOF | Doesn't work on Windows |
| Ctrl+U | Delete from the current position to the line start | |
| Ctrl+K | Delete from the current position to the end of line | |
| Ctrl+A | Go to start of line | |
| Ctrl+E | Go to end of line | |
| Ctrl+B | Back one character | |
| Ctrl+F | Forward one character | |
| Ctrl+L | Clear screen | |
| Ctrl+N | Next history item | |
| Ctrl+P | Previous history item | |
| Ctrl+Z | Moves running process into background. Type
fg and press Enter
to return. |
Doesn't work on Windows |
| Ctrl+W or Ctrl +Backspace | Delete backward to a word boundary | Ctrl+Backspace Doesn't work on Linux, Mac and Windows |
| Ctrl+Delete | Delete forward to a word boundary | Doesn't work on Mac |
| Ctrl+Left arrow or Meta+B | Word left | Ctrl+Left arrow Doesn't work on Mac |
| Ctrl+Right arrow or Meta+F | Word right | Ctrl+Right arrow Doesn't work on Mac |
| Meta+D or Meta +Delete | Delete word right | Meta+Delete Doesn't work on windows |
| Meta+Backspace | Delete word left | Doesn't work on Mac |