RingoJSには、read
と呼ばれる function があり、最後に到達するまでストリーム全体を読み取ることができます。これは、コマンドラインアプリケーションを作成するときに役立ちます。たとえば、次のようにtac
program と書くことができます。
#!/usr/bin/env ringo
var string = system.stdin.read(); // read the entire input stream
var lines = string.split("\n"); // split the lines
lines.reverse(); // reverse the lines
var reversed = lines.join("\n"); // join the reversed lines
system.stdout.write(reversed); // write the reversed lines
これにより、シェルを起動してtac
コマンドを実行できます。次に、必要な数の行を入力し、完了したらを押すことができます Ctrl+D (または Ctrl+Z Windowsの場合) 送信の終了 を通知します。
Node.jsで同じことをしたいのですが、そうする関数が見つかりません。 readSync
ライブラリのfs
function を使用して、次のようにシミュレートすることを考えましたが、役に立ちませんでした。
fs.readSync(0, buffer, 0, buffer.length, null);
stdinのファイル記述子 (最初の引数)は0
。したがって、キーボードからデータを読み取る必要があります。代わりに、次のエラーが発生します。
Error: ESPIPE, invalid seek
at Object.fs.readSync (fs.js:381:19)
at repl:1:4
at REPLServer.self.eval (repl.js:109:21)
at rli.on.self.bufferedCmd (repl.js:258:20)
at REPLServer.self.eval (repl.js:116:5)
at Interface.<anonymous> (repl.js:248:12)
at Interface.EventEmitter.emit (events.js:96:17)
at Interface._onLine (readline.js:200:10)
at Interface._line (readline.js:518:8)
at Interface._ttyWrite (readline.js:736:14)
入力テキストストリーム内のすべてのデータを同期的に収集し、node.jsで文字列として返すにはどうすればよいですか?コード例は非常に役立ちます。
重要なのは、次の2つのストリームイベントを使用することです。
_Event: 'data'
Event: 'end'
_
stream.on('data', ...)
の場合、データデータをバッファ(バイナリの場合)または文字列に収集する必要があります。
on('end', ...)
の場合、完了したバッファーを使用してコールバックを呼び出すか、インライン化してPromisesライブラリを使用してreturnを使用できる場合。
Node.jsはイベントとストリーム指向であるため、stdinとバッファーの結果が終了するまで待機するAPIはありませんが、手動で行うのは簡単です。
var content = '';
process.stdin.resume();
process.stdin.on('data', function(buf) { content += buf.toString(); });
process.stdin.on('end', function() {
// your code here
console.log(content.split('').reverse().join(''));
});
ほとんどの場合、データをバッファリングせず、到着時に着信チャンクを処理しない方がよいでしょう(xmlやzlibなどのすでに利用可能なストリームパーサーのチェーンまたは独自のFSMパーサーを使用)
concat-streamと呼ばれるその特定のタスク用のモジュールがあります。
StreetStriderの答えを説明しましょう。
concat-stream でそれを行う方法は次のとおりです
var concat = require('concat-stream');
yourStream.pipe(concat(function(buf){
// buf is a Node Buffer instance which contains the entire data in stream
// if your stream sends textual data, use buf.toString() to get entire stream as string
var streamContent = buf.toString();
doSomething(streamContent);
}));
// error handling is still on stream
yourStream.on('error',function(err){
console.error(err);
});
その点に注意してください process.stdin
はストリームです。