情報アイランド

「情報を制する者は世界を制す」をモットーに様々な情報を提供することを目指すブログです。現在はプログラミング関連情報が多めですが、投資関連情報も取り扱っていきたいです。

Node.jsで独自の読み書きストリームを作成する

独自の読み書きストリームを作成するにはstream.Duplexクラスのコンストラクタを使用します。

var stream = require('stream');

var duplex = new stream.Duplex({
    objectMode: false, 
    readableObjectMode: false, 
    writableObjectMode: false, 
    highWaterMark: 16384, 
    decodeStrings: true, 
    encoding: null, 
    allowHalfOpen: true, 
    write: function (chunk, encoding, callback) {
        callback(null);
        //or
        callback(new Error('xxx'));
    }, 
    writev: function (chunks, callback) {
        callback(null);
        //or
        callback(new Error('xxx'));
    }, 
    read: function (size) {
        this.push('xxx', 'yyy');
    }
});

第1引数にオプションをオブジェクトとして指定します。

オプションには下のようなものがあります。

  • readableObjectMode・・・文字列やバッファ以外のデータの読み込みが可能であるかを真偽値として指定します。デフォルトはfalseです。ただし、objectModeオプションがtrueである場合には無視されます。
  • writableObjectMode・・・文字列やバッファ以外のデータの書き込みが可能であるかを真偽値として指定します。デフォルトはfalseです。ただし、objectModeオプションがtrueである場合には無視されます。
  • allowHalfOpen・・・読み込みストリームと書き込みストリームの片方のみが開いている状態を許容するかを真偽値として指定します。falseである場合には一方のストリームが閉じた場合には他方のストリームは自動的に閉じられます。デフォルトはtrueです。

また、stream.Writableクラスのコンストラクタやstream.Readableクラスのコンストラクタの第1引数のオプションを指定することもできます。

サンプルコード1

duplex.js

var stream = require('stream');

var i = 0;
var duplex = new stream.Duplex({
    decodeStrings: false, 
    encoding: 'utf-8', 
    write: function (chunk, encoding, callback) {
        if (chunk.length > 10) {
            console.log('** %s... **', chunk.substring(0, 10));
        }
        else {
            console.log('** %s **', chunk);
        }
        callback(null);
    }, 
    read: function (size) {
        var f = true;
        for (; i < 10 && f; i++) {
            f = this.push(Math.random().toString());
        }
        if (i == 10) {
            this.push(null);
        }
    }
});
duplex.on('error', function (err) {
    console.error(err);
    process.exit(1);
});

duplex.write('foo');
duplex.write('foofoo');
duplex.write('foofoofoo');
duplex.write('foofoofoofoo');
duplex.write('foofoofoofoofoo');
duplex.end();

duplex.on('data', function (r) {
    console.log(r);
});
duplex.on('end', function () {
    console.log('end.');
});

実行結果

C:\work\node>node duplex.js
** foo **
** foofoo **
** foofoofoo **
** foofoofoof... **
** foofoofoof... **
0.25384401369108023
0.9993649836806029
0.8338362287349301
0.16746988038601685
0.08218512094217933
0.051235986439121195
0.22465603940344891
0.008913409803031236
0.34708226564833544
0.3126645648535651
end.

関連

pizyumi
プログラミング歴19年のベテランプログラマー。業務システム全般何でも作れます。現在はWeb系の技術を勉強中。
スポンサーリンク

-Node.js