node.js を使用して HTTP リクエストを作成し、Web サーバーからテキストをロードします。応答には大量のテキスト (数メガバイト) が含まれる可能性があるため、各テキスト チャンクを個別に処理します。次のコードを使用してこれを実現できます。
var req = http.request(reqOptions, function(res) {
...
res.setEncoding('utf8');
res.on('data', function(textChunk) {
// process utf8 text chunk
});
});
これは問題なく動作するようです。ただし、HTTP 圧縮をサポートしたいので、zlib を使用します。
var zip = zlib.createUnzip();
// NO res.setEncoding('utf8') here since we need the raw bytes for zlib
res.on('data', function(chunk) {
// do something like checking the number of bytes downloaded
zip.write(chunk); // give the raw bytes to zlib, s.b.
});
zip.on('data', function(chunk) {
// convert chunk to utf8 text:
var textChunk = chunk.toString('utf8');
// process utf8 text chunk
});
これは、とのような'\u00c4'
2 つのバイトで構成されるマルチバイト文字の場合に問題になることがあります。最初のバイトが最初のチャンク ( ) でカバーされ、2 番目のバイトが 2 番目のチャンクでカバーされる場合、テキスト チャンクの最後または先頭に誤った文字が生成されます。どうすればこれを回避できますか?0xC3
0x84
Buffer
chunk.toString('utf8')
ヒント: ダウンロードされるバイト数を制限するには、バッファ (より具体的にはバッファ内のバイト数) が必要です。したがって、res.setEncoding('utf8')
非圧縮データに対して上記の最初のサンプル コードのように使用することは、私のニーズには適していません。
ベストアンサー1
シングルバッファ
シングルをお持ちの場合はBuffer
、toString
特定のエンコーディングを使用して、バイナリ コンテンツのすべてまたは一部を文字列に変換するメソッドです。utf8
パラメータを指定しない場合はデフォルトで になりますが、この例では明示的にエンコーディングを設定しています。
var req = http.request(reqOptions, function(res) {
...
res.on('data', function(chunk) {
var textChunk = chunk.toString('utf8');
// process utf8 text chunk
});
});
ストリームバッファ
上記の質問のように、マルチバイトUTF8
文字の最初のバイトが最初の(チャンク)に含まれBuffer
、2番目のバイトが2番目のチャンクに含まれる可能性があるストリームBuffer
バッファがある場合は、StringDecoder
. :
var StringDecoder = require('string_decoder').StringDecoder;
var req = http.request(reqOptions, function(res) {
...
var decoder = new StringDecoder('utf8');
res.on('data', function(chunk) {
var textChunk = decoder.write(chunk);
// process utf8 text chunk
});
});
この方法でバイトの不完全なStringDecoder
必要なすべてのバイトがデコーダーに書き込まれるまで、文字はバッファリングされます。