2016-04-02 7 views
3

でストリームを変換:セットエンコーディングはReadableストリームのためnodeJS <a href="https://nodejs.org/api/stream.html#stream_readable_setencoding_encoding" rel="nofollow">docs(v5.10.0)</a>によると、安全な方法

バッファが直接buf.toString(encoding)を使用しての作業よりもreadable.setEncoding('utf8')を使用することをお勧めします。これは 「マルチバイト文字(...)がそうでない場合は、潜在的にマングルされただろうので、あなたが文字列としてデータを読みたい場合は 。で、常にこのメソッドを使用します。

私の質問はこれを実装する方法についてですストリームを変換するための新しいAPIを使用して。相続冗長な方法を通過する今必要はありません。

ので、例えばこれは大文字の文字列

const transform = require("stream").Transform({ 
    transform: function(chunk, encoding, next) { 
    this.push(chunk.toString().toUpperCase()); 
    next(); 
    } 
}); 

process.stdin.pipe(transform).pipe(process.stdout); 

に標準入力を変換するための方法として働くだろうしかし、これはt oバッファー上でtoString()を使用しないという推奨に反する。第二に、それが実際に変化したのに対し、第一の場合にtransformは、ヌルの符号を有し、検査の際

const transform = require("stream").Transform({ 
    transform: function(chunk, encoding, next) { 
    this.push(chunk.toUpperCase()); //chunk is a buffer so this doesn't work 
    next(); 
    } 
}); 
transform.setEncoding("utf-8"); 

process.stdin.pipe(transform).pipe(process.stdout); 

:私はこのような「UTF-8」にエンコーディングを設定することにより、変換インスタンスを修正しようとしました"utf-8"しかし、変換関数に渡されるチャンクはまだバッファです。私は符号化toString()メソッドをスキップすることができたと思ったが、そうではない。

私も読み取り可能とデュプレックスの例のようにread方法を拡張しようとしたが、それは許可されていません。

toString()を取り除く方法はありますか?

答えて

1

あなたが正しいです。 _transformメソッドで直接Buffer#toStringを使用するのは悪いです。しかし、setEncodingが読めるストリーム消費者(トランスフォームストリームから読み込むすなわちコード)によって使用されることを意味しています。あなたは変換ストリームを実装しています。 _transformメソッドの入力は変更されません。消費者が自己復号化を活性化する場合

は内部的には、読み取り可能なストリームはStringDecoderを使用します。変換メソッドでも同様に使用できます。

は、ここでそれがどのように機能するかを説明code commentです:

[StringDecoder]は、与えられたバッファをデコードし、任意の部分的なマルチバイト文字が含まれていないことが保証されるJS文字列として返します。バッファの最後に見つかった部分文字はバッファリングされ、残りのバイトとともに再度writeを呼び出すと返されます。

次のように、あなたの例を書き換えることができます

var StringDecoder = require('string_decoder').StringDecoder 
const transform = require("stream").Transform({ 
    transform: function(chunk, encoding, next) { 
    if(!this.myStringDecoder) this.myStringDecoder = new StringDecoder('utf8') 
    this.push(this.myStringDecoder.write().toUpperCase()); 
    next(); 
    } 
}); 

process.stdin.pipe(transform).pipe(process.stdout); 
+0

私の最初のスニペットはそのまま動作しますので、直接StringDecoderを使用する必要がないでしょう。私は困惑していますドキュメントはそれがインスタンスを変換「リード・ライト可能インターフェースの両方を実装する」と言うとき、あなたはケースではないよう言っている何のため。StringDecoderは、読み取り可能なものとまったく逆の動作をします – cortopy

+0

あなたのスニペットは、マルチバイト文字が異なるチャンクに区切られていない限り動作します。テキストを扱うトランスフォームストリームには、文字列デコーダを使うことをお勧めします。ドキュメントは少し曖昧です。単に「ストリームを返すようにこの関数を呼び出す」と書かれていますが、これは*消費者の*セクションなので、これは実装者には何の影響もないことは明らかです。 StringDecoderはお勧めしていないと思いますか? –

+0

変換ストリームの消費側も制御するならば、 'process.stdin'に対して' setEncoding'を呼び出すことができます。 –

関連する問題

 関連する問題