node之readline(逐行读取)

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流中

  • data <string>

  • key <Object>

    • ctrl <boolean> 如果为 true 则表示 <ctrl> 键。
    • meta <boolean> 如果为 true 则表示 <Meta> 键。
    • shift <boolean> 如果为 true 则表示 <Shift> 键。
    • name <string> 一个按键的名称。
      rl.write() 方法会把 data 或一个由 key 指定的按键序列写入到 output。 只有当 output 是一个 TTY 文本终端时,key 参数才被支持。

readline.clearLine(stream, dir)

会以dir指定的方向清除给定的TTY流的当前行

readline.clearScreenDown(stream)

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

readline.createInterface(options)

  • options <Object>

    • input <stream.Readable> 要监听的可读流。该选项是必需的。
    • output <stream.Writable> 要写入逐行读取数据的可写流
    • completer <Function> 一个可选的函数,用于 Tab 自动补全。
    • terminal <boolean> 如果 inputoutput 应被当作一个 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)

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}`);
})
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,634评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,951评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,427评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,770评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,835评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,799评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,768评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,544评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,979评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,271评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,427评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,121评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,756评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,375评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,579评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,410评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,315评论 2 352

推荐阅读更多精彩内容

  • https://nodejs.org/api/documentation.html 工具模块 Assert 测试 ...
    KeKeMars阅读 6,320评论 0 6
  • Node.js中文网的 v6.10.3 文档提供了readline模块,可以从可读流(process.stdin)...
    Evtion阅读 5,458评论 0 4
  • 官网 中文版本 好的网站 Content-type: text/htmlBASH Section: User ...
    不排版阅读 4,380评论 0 5
  • 五月
    d6a75dc9aae8阅读 171评论 0 0
  • 願望:1願望盧鋒8月22日打了2萬分繼續住表演套房!2願望丁向東總共打了2萬分!3願望業績快速沖破600萬!感恩:...
    謝奕鋒阅读 65评论 0 0