Node.js 逐行读取 Node.js C C++ 插件 Node.js 全局对象 Node.js 逐行读取 本节介绍Node.js readline(逐行读取)模块,它用于提供一个接口。 稳定性: 2 - 不稳定 通过 require('readline'),你可以使用这个模块。逐行读取(Readline)可以逐行读取流(比如process.stdin)。 访问该模块的方法如下: const readline = require('readline'); 一旦你开启了这个模块,node程序将不会终止,直到你关闭接口。以下的代码展示了如何优雅的退出程序: var readline = require('readline'); var rl = readline.createInterface({ input: process.stdin, output: process.stdout }); rl.question("What do you think of node.js? ", function(answer) { // TODO: Log the answer in a database console.log("Thank you for your valuable feedback:", answer); rl.close(); }); readline.createInterface(options) 创建一个逐行读取(Readline)Interface实例。参数"options"对象有以下值: input- 监听的可读流 (必填)。 output- 逐行读取(Readline)数据要写入的可写流(可选)。 completer- 用于Tab自动补全的可选函数。参见下面的例子。 terminal- 如果希望和TTY一样,对待input和output流,设置为true。并且由ANSI/VT100转码。默认情况下,检查isTTY是否在output流上实例化。 completer给出当前行的入口,应该返回包含2条记录的数组。 一个匹配当前输入补全的字符串数组 用来匹配的子字符串 最终像这样:[[substr1, substr2, ...], originalsubstring]. 例子: function completer(line) { var completions = '.help .error .exit .quit .q'.split(' ') var hits = completions.filter(function(c) { return c.indexOf(line) == 0 }) // show all completions if none found return [hits.length ? hits : completions, line] } 同时,completer可以异步运行,此时接收到2个参数: function completer(linePartial, callback) { callback(null, [['123'], linePartial]); } 为了接受用户输入,createInterface通常和process.stdin ,process.stdout一起使用: var readline = require('readline'); var rl = readline.createInterface({ input: process.stdin, output: process.stdout }); 如果你有逐行读取(Readline)实例, 通常会监听"line"事件. 如果这个实例参数terminal = true,而且定义了output.columns属性,那么output流将会最佳兼容性,并且,当columns变化时(当它是TTY时,process.stdout会自动这么做),会在output流上触发"resize"事件。 Class: Interface 代表一个包含输入/输出流的逐行读取(Readline)接口的类。 rl.setPrompt(prompt) 设置提示符,比如当你再命令行里运行node时,可以看到node的提示符>。 rl.prompt([preserveCursor]) 为用户输入准备好逐行读取(Readline),将当前setPrompt选项方法哦新的行中,让用户有新的地方输入。设置preserveCursor为true,防止当前的游标重置为0。 如果暂停,使用createInterface也可以重置input输入流。 调用createInterface时,如果output设置为null或undefined,不会重新写提示符。 rl.question(query, callback) 预先提示query,用户应答后触发callback。给用户显示query后,用户应答被输入后,调用callback。 如果暂停,使用createInterface也可以重置input输入流。 调用createInterface时,如果output设置为null或undefined,不会重新写提示符。 例子: interface.question('What is your favorite food?', function(answer) { console.log('Oh, so your favorite food is ' + answer); }); rl.pause() 暂停逐行读取(Readline)的input输入流, 如果需要可以重新启动。 注意,这不会立即暂停流。调用pause后还会有很多事件触发,包含line。 rl.resume() 恢复 逐行读取(Readline)input输入流. rl.close() 关闭Interface实例, 放弃控制输入输出流。会触发"close"事件。 rl.write(data[, key]) 调用createInterface后,将数据data写到output输出流,除非output为null,或未定义undefined。key是一个代表键序列的对象;当终端是一个 TTY 时可用。 暂停input输入流后,这个方法可以恢复。 例子: rl.write('Delete me!'); // Simulate ctrl+u to delete the line written previously rl.write(null, {ctrl: true, name: 'u'}); Events 事件: 'line' function (line) {} input输入流收到\n后触发,通常因为用户敲回车或返回键。这是监听用户输入的好办法。 监听line的例子: rl.on('line', function (cmd) { console.log('You just typed: '+cmd); }); 事件: 'pause' function () {} 暂停input输入流后,会触发这个方法。 当输入流未被暂停,但收到SIGCONT也会触发。 (详见SIGTSTP和SIGCONT事件) 监听pause的例子: rl.on('pause', function() { console.log('Readline paused.'); }); 事件: 'resume' function () {} 恢复input输入流后,会触发这个方法。 监听resume的例子: rl.on('resume', function() { console.log('Readline resumed.'); }); 事件: 'close' function () {} 调用close()方法时会触发。 当input输入流收到"end"事件时会触发。一旦触发,可以认为Interface实例结束。例如当input输入流收到^D,被当做EOT。 如果没有SIGINT事件监听器,当input 输入流接收到^C(被当做SIGINT),也会触发这个事件。 事件: 'SIGINT' function () {} 当input输入流收到^C时会触发, 被当做SIGINT。如果没有SIGINT 事件监听器,当input 输入流接收到SIGINT(被当做SIGINT),会触发 pause事件。 监听SIGINT的例子: rl.on('SIGINT', function() { rl.question('Are you sure you want to exit?', function(answer) { if (answer.match(/^y(es)?$/i)) rl.pause(); }); }); 事件: 'SIGTSTP' function () {} Windows 里不可用 当input输入流收到^Z时会触发,被当做SIGTSTP。如果没有SIGINT事件监听器,当input 输入流接收到SIGTSTP,程序将会切换到后台。 当程序通过fg恢复,将会触发pause和SIGCONT事件。你可以使用两者中任一事件来恢复流。 程切换到后台前,如果暂停了流,pause和 SIGCONT事件不会被触发。 监听SIGTSTP的例子: rl.on('SIGTSTP', function() { // This will override SIGTSTP and prevent the program from going to the // background. console.log('Caught SIGTSTP.'); }); 事件: 'SIGCONT' function () {} Windows里不可用 一旦input流中含有^Z并被切换到后台就会触发。被当做SIGTSTP,然后继续执行fg(1)。程切换到后台前,如果流没被暂停,这个事件可以被触发。 监听SIGCONT的例子: rl.on('SIGCONT', function() { // `prompt` will automatically resume the stream rl.prompt(); }); 例子: Tiny CLI 以下的例子,展示了如何所有这些方法的命令行接口: var readline = require('readline'), rl = readline.createInterface(process.stdin, process.stdout); rl.setPrompt('OHAI> '); rl.prompt(); rl.on('line', function(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', function() { console.log('Have a great day!'); process.exit(0); }); readline.cursorTo(stream, x, y) 在TTY流里,移动光标到指定位置。 readline.moveCursor(stream, dx, dy) 在TTY流里,移动光标到当前位置的相对位置。 readline.clearLine(stream, dir) 清空TTY流里指定方向的行。dir是以下值: -1- 从光标到左边 1- 从光标到右边 0- 整行 readline.clearScreenDown(stream) 清空屏幕上从当前光标位置起的内容。 Node.js C C++ 插件 Node.js 全局对象