ホームページ >ウェブフロントエンド >jsチュートリアル >Nodejs の書き込み可能なストリームとは何ですか?使い方
関連する推奨事項: 「nodejs チュートリアル 」
書き込み可能な Aストリームは、デバイスに流れるデータの抽象化です。上流から流れるデータを消費するために使用されます。データは、書き込み可能なストリーム プログラムを通じてデバイスに書き込むことができます。一般的に使用されるのは、ローカル ディスク ファイルまたは TCP や HTTP などのネットワーク応答です。
前に使用した例を見てください。
process.stdin.pipe(process.stdout);
*process.stdout* は書き込み可能なストリームであり、プログラムは読み取り可能なストリーム process.stdin 入力によって渡されたデータを書き込みます。標準出力デバイス。読み取り可能なストリームを理解することに基づいて書き込み可能なストリームを理解することは非常に簡単です。ストリームは方向性のあるデータであり、読み取り可能なストリームがデータ ソース、書き込み可能なストリームが宛先、中間のパイプライン リンクがデータです。双方向ストリーム。
書き込み可能なストリーム インスタンスの **write() ** メソッドを呼び出して、書き込み可能なストリームにデータを書き込みます
const fs = require('fs'); const rs = fs.createReadStream('./w.js'); const ws = fs.createWriteStream('./copy.js'); rs.setEncoding('utf-8'); rs.on('data', chunk => { ws.write(chunk); });
前述したように、読み取り可能ストリームのデータ イベントをリッスンすると、読み取り可能ストリームがフロー モードになり、コールバック イベントで書き込み可能ストリームの write() メソッドを呼び出して、データが書き込み可能ストリームに書き込まれます。抽象デバイス、つまり現在のディレクトリ内の copy.js ファイル内。
write() メソッドには 3 つのパラメータ
const Writable = require('stream').Writable class OutputStream extends Writable { _write(chunk, enc, done) { // 转大写之后写入标准输出设备 process.stdout.write(chunk.toString().toUpperCase()); // 此处不严谨,应该是监听写完之后才调用 done process.nextTick(done); } } module.exports = OutputStream;
書き込み可能なストリームのインスタンス化
イベント
pipe読み取り可能ストリームが Pipe() メソッドを呼び出してデータを書き込み可能ストリームに送信すると、書き込み可能ストリームのパイプ イベントがトリガーされます
- unpipe
読み取り可能ストリームが unpipe() メソッドを呼び出してデータ転送を削除すると、書き込み可能ストリームの unpipe イベントがトリガーされます。- これら 2 つのイベントは、次の目的で使用されます。書き込み可能なストリームデータが来る、または途切れるという通知は、通常の状況ではほとんど使用されません。
writeable.write()
このメソッドには bool 戻り値があり、前述のhighWaterMark のように、書き込む必要のあるデータが、 writable stream この時、データは一気に書き込まれず、一部のデータが残りますが、このとき writeable.write() は false を返し、処理可能であれば、 return true
drain以前に取り残されたデータがあった場合、つまり writeable.write() が false を返した場合にトリガーされます。消化期間の後、データのバックログが処理されますそして新しいデータを書き続けることができます (排水の本来の目的) それは排水と枯渇です、非常に鮮やかです)
除了 write() 方法可写流还有一个常用的方法 end(),参数和 write() 方法相同,但也可以不传入参数,表示没有其它数据需要写入,可写流可以关闭了。
finish 当调用 writable.end() 方法,并且所有数据都被写入底层后会触发 finish 事件
同样出现错误后会触发 error 事件
了解了这些事件,结合上之前提到的可读流的一些知识,我们就能探讨一些有意思的话题了。在最开始我们提到过用流相对于直接操作文件的好处之一是不会把内存压爆,那么流是怎么做到的呢?
最开始我们可能会想到因为流不是一次性把所有数据载入内存处理,而是一边读一边写。但我们知道一般读取的速度会远远快于写入的速度,那么 pipe() 方法是怎么做到供需平衡的呢?
回忆一些基础知识,我们自己来实现一下 pipe() 方法的核心原理
我们可以利用这三点来做到数据读取和写入的同步,还是使用之前的例子,但为了使消费速度降下来,我们各一秒再通知完成
class OutputStream extends Writable { _write(chunk, enc, done) { // 转大写之后写入标准输出设备 process.stdout.write(chunk.toString().toUpperCase()); // 故意延缓通知继续传递数据的时间,造成写入速度慢的现象 setTimeout(done, 1000); } }
我们使用一下自定义的两个类
const RandomNumberStream = require('./RandomNumberStream'); const OutputStream = require('./OutputStream'); const rns = new RandomNumberStream(100); const os = new OutputStream({ highWaterMark: 8 // 把水位降低,默认16k还是挺大的 }); rns.on('data', chunk => { // 当待处理队列大于 highWaterMark 时返回 false if (os.write(chunk) === false) { console.log('pause'); rns.pause(); // 暂停数据读取 } }); // 当待处理队列小于 highWaterMark 时触发 drain 事件 os.on('drain', () => { console.log('drain') rns.resume(); // 恢复数据读取 });
结合前面的三点和注释很容易看懂上面代码,这就是 pipe() 方法起作用的核心原理。数据的来源的去向我们有了大概了解,后面可以开始介绍数据的加工
更多编程相关知识,请访问:编程学习课程!!
以上がNodejs の書き込み可能なストリームとは何ですか?使い方の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。