web-dev-qa-db-ja.com

JavaScriptオブジェクトからNode.js読み取り可能なストリームを作成する—可能な限り簡単な方法

ノードv0.10.21で次のコードを実行した後にエラーが発生する理由を誰かが説明できますか?

ほぼ同じ結果を達成するためにそのオブジェクトをJSON.stringify()できることを知っています。ここでのポイントは、objectModeがtrueに設定されているときにstream.Readableを理解することです。

エラー:

net.js:612
    throw new TypeError('invalid data');
          ^
TypeError: invalid data
    at WriteStream.Socket.write (net.js:612:11)
    at write (_stream_readable.js:583:24)
    at flow (_stream_readable.js:592:7)
    at _stream_readable.js:560:7
    at process._tickCallback (node.js:415:13)
    at Function.Module.runMain (module.js:499:11)
    at startup (node.js:119:16)
    at node.js:901:3

コード:

var stream = require('stream');
var edad = require(__dirname + '/public/edad.json');

var rs = new stream.Readable({ objectMode: true });

rs.Push(edad);
rs.Push(null);
rs.pipe(process.stdout);
17
n370

rsはobjectModeストリームですが、process.stdoutはそうではないので、Bufferインスタンスが書き込まれることを期待しています。間違ったデータ型を取得しているため、エラーをスローしています。

このようにオブジェクトをパイプ処理できるようにするには、オブジェクトとしての書き込みとバッファとしての読み取りをサポートする中間ストリームが必要です。

このようなもの:

var stream = require('stream');
var util = require('util');

function StringifyStream(){
    stream.Transform.call(this);

    this._readableState.objectMode = false;
    this._writableState.objectMode = true;
}
util.inherits(StringifyStream, stream.Transform);

StringifyStream.prototype._transform = function(obj, encoding, cb){
    this.Push(JSON.stringify(obj));
    cb();
};


var edad = require(__dirname + '/public/edad.json');

var rs = new stream.Readable({ objectMode: true });
rs.Push(edad);
rs.Push(null);

rs.pipe(new StringifyStream()).pipe(process.stdout);
21
loganfsmyth

Loganfsmythが指摘したように、rsobjectModeにあり、process.stdoutはそうではありません。したがって、Buffers/Stringsが書き込まれることを期待しており、TypeErrorを取得するとObjectをスローします。

オブジェクトのストリームをテキストに変換する必要があります。これが JSONStream の処理です。

JSONStream = require('JSONStream');
rs.pipe(JSONStream.stringify()).pipe(process.stdout);
4
slang

私はNodeについてあまり詳しくない人です(Gulpの設定を機能させる必要があるだけです)。そのため、20行以上のコードと奇妙な呼び出しが必要です。 stream.Push(null)ストリームで変数を操作するのは少しおかしいようです。

これは私のために働きました:

var data = { "prop1": "val1", "prop2": "val2" };
var dest = 'path/to/dest/config.json';
var s = require('stream');

var stream = new s.Readable();
stream.Push(JSON.stringify(data));    // stream apparently does not accept objects
stream.Push(null);                    // no idea why this is needed, but it is

return stream
    .pipe()                           // whatever you need
    .pipe($.fs.createWriteStream(dest));
2
Petr Cibulka