鍍金池/ 教程/ HTML/ 逐行讀取
模塊
斷言測試
Buffer
Smalloc
TTY
概述
REPL
HTTP
DNS
路徑
集群
TLS/SSL
系統(tǒng)
加密
調(diào)試器
進程
Punycode
虛擬機
HTTPS
網(wǎng)絡
Query String
C/C++ 插件
實用工具
文件系統(tǒng)
Zlib
子進程
UDP/Datagram Sockets
定時器
逐行讀取
字符串解碼器
全局對象
事件
URL
控制臺

逐行讀取

穩(wěn)定性: 2 - 不穩(wěn)定

使用 require('readline'),可以使用這個模塊。逐行讀?。≧eadline)可以逐行讀取流(比如process.stdin

一旦你開啟了這個模塊,node 程序?qū)⒉粫K止,直到你關閉接口。以下的代碼展示了如何優(yōu)雅的退出程序:

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)

創(chuàng)建一個逐行讀?。≧eadline) Interface 實例. 參數(shù) "options" 對象有以下值:

  • input - 監(jiān)聽的可讀流 (必填).

  • output - 逐行讀?。≧eadline)數(shù)據(jù)要寫入的可寫流(可選).

  • completer - 用于 Tab 自動補全的可選函數(shù)。參見下面的例子。

  • terminal - 如果希望和 TTY 一樣,對待 inputoutput 流,設置為 true。 并且由 ANSI/VT100 轉(zhuǎn)碼。默認情況下,檢查 isTTY 是否在 output 流上實例化。

completer 給出當前行的入口,應該返回包含2條記錄的數(shù)組

  1. 一個匹配當前輸入補全的字符串數(shù)組

  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個參數(shù):

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
});

如果你有逐行讀?。≧eadline)實例, 通常會監(jiān)聽"line" 事件.

如果這個實例參數(shù) terminal = true,而且定義了 output.columns 屬性,那么 output 流將會最佳兼容性,并且,當 columns 變化時(當它是 TTY 時,process.stdout 會自動這么做),會在 output 流上觸發(fā) "resize" 事件。

Class: Interface

代表一個包含輸入/輸出流的逐行讀取(Readline)接口的類,

rl.setPrompt(prompt)

設置提示符,比如當你再命令行里運行 node 時,可以看到 node 的提示符 >。

rl.prompt([preserveCursor])

為用戶輸入準備好逐行讀?。≧eadline),將當前 setPrompt 選項方法哦新的行中,讓用戶有新的地方輸入。設置 preserveCursortrue,防止當前的游標重置為 0。

如果暫停,使用 createInterface也可以重置input 輸入流。

調(diào)用 createInterface 時,如果 output 設置為 nullundefined ,不會重新寫提示符。

rl.question(query, callback)

預先提示 query,用戶應答后觸發(fā) callback。給用戶顯示 query 后,用戶應答被輸入后,調(diào)用 callback。

如果暫停,使用 createInterface也可以重置input 輸入流。

調(diào)用 createInterface 時,如果 output 設置為 nullundefined ,不會重新寫提示符。

例子:

interface.question('What is your favorite food?', function(answer) {
  console.log('Oh, so your favorite food is ' + answer);
});

rl.pause()

暫停逐行讀?。≧eadline)的 input 輸入流, 如果需要可以重新啟動。

注意,這不會立即暫停流。調(diào)用 pause 后還會有很多事件觸發(fā),包含 line。

rl.resume()

恢復 逐行讀?。≧eadline) input 輸入流.

rl.close()

關閉 Interface 實例, 放棄控制輸入輸出流。會觸發(fā)"close" 事件。

rl.write(data[, key])

調(diào)用createInterface 后,將數(shù)據(jù) data 寫到 output 輸出流,除非 outputnull,或未定義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 后觸發(fā),通常因為用戶敲回車或返回鍵。這是監(jiān)聽用戶輸入的好辦法。

監(jiān)聽 line 的例子:

rl.on('line', function (cmd) {
  console.log('You just typed: '+cmd);
});

事件: 'pause'

function () {}

暫停 input 輸入流后,會觸發(fā)這個方法。

當輸入流未被暫停,但收到 SIGCONT 也會觸發(fā)。 (詳見 SIGTSTPSIGCONT 事件)

監(jiān)聽 pause 的例子:

rl.on('pause', function() {
  console.log('Readline paused.');
});

事件: 'resume'

function () {}

恢復 input 輸入流后,會觸發(fā)這個方法。

監(jiān)聽 resume 的例子:

rl.on('resume', function() {
  console.log('Readline resumed.');
});

事件: 'close'

function () {}

調(diào)用 close() 方法時會觸發(fā)。

input 輸入流收到 "end" 事件時會觸發(fā)。一旦觸發(fā),可以認為 Interface 實例結(jié)束。例如當input 輸入流收到 ^D,被當做 EOT。

如果沒有SIGINT 事件監(jiān)聽器,當input 輸入流接收到^C(被當做SIGINT),也會觸發(fā)這個事件。

事件: 'SIGINT'

function () {}

input 輸入流收到 ^C 時會觸發(fā), 被當做SIGINT。如果沒有SIGINT 事件監(jiān)聽器,當input 輸入流接收到 SIGINT(被當做SIGINT),會觸發(fā) pause 事件。

監(jiān)聽 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 時會觸發(fā),被當做SIGTSTP。如果沒有SIGINT 事件監(jiān)聽器,當input 輸入流接收到 SIGTSTP,程序?qū)袚Q到后臺。

當程序通過 fg 恢復,將會觸發(fā) pauseSIGCONT 事件。你可以使用兩者中任一事件來恢復流。

程切換到后臺前,如果暫停了流,pauseSIGCONT 事件不會被觸發(fā)。

監(jiān)聽 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并被切換到后臺就會觸發(fā)。被當做SIGTSTP,然后繼續(xù)執(zhí)行 fg(1)。程切換到后臺前,如果流沒被暫停,這個事件可以被觸發(fā)。

監(jiān)聽 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)

清空屏幕上從當前光標位置起的內(nèi)容。

上一篇:文件系統(tǒng)下一篇:系統(tǒng)