1. ホーム
  2. node.js

[解決済み】ストリームバッファをutf8-stringに変換する。

2022-04-15 17:18:51

質問

私はウェブサーバーからいくつかのテキストを読み込むためにnode.jsを使用してHTTP-requestを作成したいと思います。応答は多くのテキスト(数メガバイト)を含むことができるので、私は各テキストチャンクを別々に処理したいと思います。私はこれを次のコードで達成することができます。

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バイトで構成されています。 0xC30x84 . 最初のバイトが最初のチャンクでカバーされている場合 ( Buffer ) で、2 バイト目が 2 番目のチャンクであれば chunk.toString('utf8') は、テキストチャンクの終わりや始まりに不正な文字を生成します。これを避けるにはどうしたらよいでしょうか?

ヒント:ダウンロードするバイト数を制限するために、やはりバッファ(より具体的にはバッファ内のバイト数)が必要です。そのため res.setEncoding('utf8') 非圧縮データの場合、上記の最初のサンプルコードのように、私のニーズには合いません。

解決方法は?

シングルバッファ

もし、単一の 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 必要なバイトがすべてデコーダに書き込まれるまで。