fs.readFileSyncとstream.onイベント徹底比較:Node.jsストリームを文字列化する最適な方法は?
Node.js ストリームを文字列変数に読み込む方法
本記事では、Node.js ストリームの内容を文字列変数に読み込む方法について、2つの代表的なアプローチと、それぞれの注意点について解説します。
fs.readFileSync 関数を使用する
fs
モジュールの readFileSync
関数は、ファイルを非同期的に読み込み、その内容を文字列として返します。ストリームを扱うわけではないため、本質的にはファイル全体を一度にメモリに読み込む方法となります。
const fs = require('fs');
const fileName = 'input.txt';
const data = fs.readFileSync(fileName, 'utf8');
console.log(data);
このコードは、input.txt
ファイルの内容を utf8
エンコーディングで読み込み、data
変数に格納します。
注意点
- ファイルサイズが大きい場合、メモリ使用量が多くなり、パフォーマンスが低下する可能性があります。
- 非常に大きなファイルを読み込む場合は、
fs.createReadStream
とon
イベントを使用する方法の方が適している場合があります。
stream.on イベントを使用する
stream.on
イベントを使用すると、ストリームからデータが読み込まれるたびにイベントを発生させることができます。読み込まれたデータを逐次的に処理し、文字列変数に蓄積していくことで、メモリ使用量を抑えながらストリーム全体の内容を読み込むことができます。
const fs = require('fs');
const fileName = 'input.txt';
const stream = fs.createReadStream(fileName, 'utf8');
let data = '';
stream.on('data', (chunk) => {
data += chunk;
});
stream.on('end', () => {
console.log(data);
});
- コードが少し複雑になる
- バックプレッシャー処理が必要になる場合がある
どちらの方法を選択すべきか
ファイルサイズが小さく、メモリ使用量を気にしなくて良い場合は、fs.readFileSync
関数を使用する方が簡潔で済みます。一方、ファイルサイズが大きい場合や、メモリ使用量を抑えたい場合は、stream.on
イベントを使用する方が適切です。
状況に応じて適切な方法を選択しましょう。
- 上記以外にも、様々なライブラリやモジュールを使用して、ストリームを文字列に変換することができます。
- より高度な処理を行う場合は、Promiseやasync/awaitを利用するのも有効です。
const fs = require('fs');
const fileName = 'input.txt';
const data = fs.readFileSync(fileName, 'utf8');
console.log(data);
説明
fs
モジュールをインポートします。- 読み込むファイル名を
fileName
変数に格納します。 fs.readFileSync
関数を使用してファイルを非同期的に読み込み、その内容をutf8
エンコーディングでdata
変数に格納します。data
変数に格納された文字列をコンソールに出力します。
const fs = require('fs');
const fileName = 'input.txt';
const stream = fs.createReadStream(fileName, 'utf8');
let data = '';
stream.on('data', (chunk) => {
data += chunk;
});
stream.on('end', () => {
console.log(data);
});
fs.createReadStream
関数を使用してファイルを読み込み可能なストリームを作成し、stream
変数に格納します。stream.on('data', (chunk) => {...})
イベントリスナーを定義します。このイベントリスナーは、ストリームからデータが読み込まれるたびに呼び出されます。chunk
変数には、読み込まれたデータチャンクが格納されます。data
変数にchunk
を連結します。
- 上記のコードはあくまで一例であり、状況に応じて自由に改変することができます。
この方法は、比較的新しい方法で、Promiseベースのアプローチとなります。
const { ReadableStream } = require('stream/web');
const { TextDecoder } = require('util');
const fileName = 'input.txt';
const stream = fs.createReadStream(fileName);
const decoder = new TextDecoder('utf8');
let data = '';
stream.on('data', (chunk) => {
data += decoder.decode(chunk);
});
stream.on('end', () => {
console.log(data);
});
stream/web
モジュールからReadableStream
クラスと、util
モジュールからTextDecoder
クラスをインポートします。TextDecoder
クラスのコンストラクタを使用して、utf8
エンコーディング用のデコーダーインスタンスを作成し、decoder
変数に格納します。decoder.decode(chunk)
メソッドを使用して、chunk
をutf8
エンコードされた文字列に変換し、data
変数に連結します。
第三者ライブラリを使用する
const streamToString = require('stream-to-string');
const fileName = 'input.txt';
const stream = fs.createReadStream(fileName);
streamToString(stream, (err, data) => {
if (err) {
console.error(err);
return;
}
console.log(data);
});
stream-to-string
ライブラリをインストールします。streamToString
関数を呼び出し、stream
とコールバック関数を引数として渡します。- コールバック関数は、エラー
err
と変換された文字列data
を引数として受け取ります。 - エラーが発生した場合は、
console.error
でエラーを出力します。 - エラーが発生しなかった場合は、
data
変数に格納された文字列をコンソールに出力します。
javascript node.js string