2017-01-05 12 views
0

は、サンプルコードは次のとおりです。Nodejs readable.read()の戻りヌル

var fs = require('fs'); 

var stream= fs.createReadStream('./lib'); 
console.log(stream.read(10)); 

リターンはnull。

read()メソッドが内部バッファから直接データを取得するためだと思います。バッファに十分なデータがない場合、nullが返されます。 read()メソッドは同期呼び出しであり、コールバックは渡されないので、設計が合理的です。 しかし、私のread()呼び出しが今すぐポーズされたモードなのでデータを返すことができるように、内部バッファに十分なデータがあることがいつわかりますか?

アップデート1:

イベントreadableが始めるには良い方法です。しかし、大きなファイルを読み込み、読み込み回数>65536の場合、nullが返されます。

var fs = require('fs'); 

var stream = fs.createReadStream('./lib'); 
stream.on('readable', function() { 
    var buffer = stream.read(65537); 
    console.log(buffer.length); 

}); 

私が正確に望むのは、stream.read()は常にEOFまでデータを返すことができます。読み込もうとする前に発射するreadableイベントの

答えて

1

待ち:

var fs = require('fs'); 

var stream= fs.createReadStream('./lib'); 
stream.on('readable', function() { 
    var buffer = stream.read(10); 
    if (buffer) { 
    console.log(buffer.toString()); 
    } 
}); 
+0

感謝。私は私のポストを更新して見てください。 'readable'イベントは完全にこの問題を解決できなかったようです。 – BartMao

0

ストリームを処理するためにチャンクでデータを読み取ります。ファイルの内容全体を取得する場合は、fs.readFile()を使用してください。それはあなたのためのデータを持っている時はいつでも

fs.readFile(FILENAME, (err, data) => { 
    console.log(Buffer.isBuffer(data)); 
    console.log(data.length); 
}) 

流れ、一方、dataイベントを発行します。デフォルトでは、このストリームのhighWaterMarkは64Kです。公式documentによると

var stream = fs.createReadStream(FILENAME); 
var results = [] 

stream.on('data', function (chunk) { 
    // For text files chunk is string 
    // for binary files chunk is an instance of Buffer 

    // do something with this chunk... 

    results.push(`Chunk ${results.length} OK`) 
}); 

stream.on('end', function() { 
    console.log(results); 
}) 
+0

あなたの答えに感謝します。あなたのコードはフローティングモードで完璧に動作しますが、一時停止モードで毎回指定された長さのバイトを読み込みたいのですが、どのようにすればいいですか?あなたのケースでは、私はそれを行うイベントハンドラの外に別のバッファを宣言することができます。 – BartMao

+0

おそらく実際に何をしようとしているのかのコードを投稿するべきでしょうか? .read()をどこから呼び出していますか? – djones

+0

ファイルの形式を解析したいと思います。例としてgifファイルを使用します。最初の3バイトはファイルヘッダーを表し、次に3はバージョンを表し、その後にサイズが固定されていない多くの異なるデータブロックが続きます。私の現在のIdeaは、.read(3)、.read(3)、.read(xx)...を個別に呼び出しています。 1つのread(xx)がバッファの終わり(デフォルトでは65536)に遭遇すると、その呼び出しはnullを返します。 – BartMao

0

内部バッファが排出されると、より多くのデータが利用可能な場合、「読みやすい」イベントが再び 起動します。

私はasync/awaitを使うことができます。そうすれば、readable.read()はEOFでなくても常にデータを返すことができます。

let rs = fs.createReadStream('./resources/1.gif'); 

async function readable(): Promise<{}> { 
    return new Promise(r => rs.on('readable', r)); 
} 

async function readBytes(num: number = 0): Promise<Buffer> { 
    let buf = rs.read(num); 
    if (buf) { 
     return new Promise<Buffer>(r => r(buf)); 
    } 
    else { 
     return new Promise<Buffer>(r => { 
      this.readable().then(() => { 
       this.readBytes(num).then(b => r(b)); 
      }); 
     }); 
    } 
} 

async function main() { 
    console.log('begin'); 
    console.log((await readBytes(10)).length); 
    console.log((await readBytes(65535)).length); 
    console.log((await readBytes(100000)).length); 
    console.log((await readBytes(10)).length); 
    console.log('end'); 
} 

main(); 

出力:良い点を与えるため

begin 
10 
65535 
100000 
10 
end 
関連する問題