はじめに
Node.jsを使っていて,Streamに触れる機会が多々あったため,改めて調べてみました。
この記事はその備忘録になります。
Streamとは
Node.jsに存在しているオブジェクトの一つで,ストリーミングデータを扱うためのオブジェクト。(公式ドキュメント)
Streamを用いることで,下記のようなメリットがあります。
- 非同期処理であるため,他の処理と並行して実行することができる。
- データを一括で処理するのではなく,一定量ずつ処理を行うため,メモリを圧迫しない。
以下でStreamを使ったサンプルコードを紹介します。
実行ファイル作成
実行ファイルの完成形
100KBのcsvファイルを読み込み,それをそのまま別ファイルに書き出します。
今回は,File System モジュールで用意されているfs.ReadStreamクラスと,fs.WriteStreamクラスを利用します。
// 必要なモジュールを読み込む
const fs = require('fs');
// 読み込み用のStreamを作成
const readStream = fs.createReadStream('100KB.csv');
// 書き込み用のStreamを作成
const writeStream = fs.createWriteStream('output.csv');
// 読み込み用のStreamにイベントリスナーを追加
// dataイベント : データが読み込まれる度に発火する
readStream.on('data', chunk => {
console.log(`chunk length = ${chunk.length} (bytes)`);
return writeStream.write(chunk)
});
// endイベント : データの読み込みが全て完了したら発火する
readStream.on('end', () => {
return writeStream.end()
});
この後一つ一つについて詳細に説明します。
読み込み用のStreamを作成
// 読み込み用のStreamを作成
const readStream = fs.createReadStream('100KB.csv');
100KBのファイルを用意し,それを読み込むためのStreamを作成します。(fs.createReadStreamメソッド)
書き込み用のStreamを作成
const writeStream = fs.createWriteStream('output.csv');
読み込んだファイルを書き込むファイルを用意し,書き込み用のStreamを作成(fs.createWriteStreamメソッド)
読み込んだファイルの内容を,別ファイルに書き込む
// 読み込み用のStreamにイベントリスナーを追加
// dataイベント : データが読み込まれる度に発火する
readStream.on('data', chunk => {
console.log(`chunk length = ${chunk.length} (bytes)`);
return writeStream.write(chunk)
});
dataイベントは,一定量のデータが読み込まれる度に発火します。
dataイベントのコールバック関数には,読み込んだデータが渡されます。(デフォルトではBufferオブジェクトが渡される)
今回は,渡されたデータをそのまま別ファイルに書き込みます。(writeable.writeメソッド)
書き込みを終了する
// endイベント : データの読み込みが全て完了したら発火する
readStream.on('end', () => {
return writeStream.end()
});
endイベントは,読み込むデータがもうない場合に発火します。
endイベントが発火したら,ファイルへの書き込みを終了させます。(writable.endメソッド)
実行
$ node sample.js
chunk length = 65536 (bytes)
chunk length = 36864 (bytes)
fs.createReadStreamメソッドで作成された読み込み用のStreamが一度に読み込むデータは,デフォルトでは64KBなので,一度目のdataイベント発火時には100KB中の64KBが読み込まれ,2度目のdataイベント発火時に残りの36KBが読み込まれている。