Node.jsを使っているときにファイルに書き込む方法を探していたのですが、うまくいきませんでした。どうすればいいのでしょうか?
File System API]1には多くの詳細が記載されています。最も一般的な方法は
const fs = require('fs');
fs.writeFile("/tmp/test", "Hey there!", function(err) {
if(err) {
return console.log(err);
}
console.log("The file was saved!");
});
現在、ファイルの書き込みには3つの方法があります。
1.1. fs.write(fd, buffer, offset, length, position, callback`).
バッファが確実にディスクに書き込まれるように、コールバックを待つ必要があります。バッファリングされていません。
2.fs.writeFile(filename, data, [encoding], callback)
.
すべてのデータを同時に保存しなければならず,逐次書き込みはできません.
3.3. fs.createWriteStream(path, [options]
).
コールバックを待たずに済むので便利なWriteStream
を作成します。しかし、やはりバッファリングされていません。
WriteStream][4]は、その名の通り、ストリーム(流れ)です。ストリームの定義は、一方向(ソース►デスティネーション)に移動するデータを含む「バッファ」です。しかし、書き込み可能なストリームは、必ずしも「バッファリング」されているわけではありません。ストリームは、
n回書き込むと「バッファリングされた」状態になり、
n+1`回目に、ストリームはバッファをカーネルに送ります(バッファがいっぱいになったので、フラッシュする必要があるからです)。
言い換えると、「バッファ」とはオブジェクトのことです。バッファリングされている」かどうかは、そのオブジェクトのプロパティです。
コードを見てみると、WriteStream
は書き込み可能なStream
オブジェクトを継承しています。注意して見てみると、コンテンツをどのようにフラッシュしているかがわかります。バッファリングシステムはありません。
文字列を書いた場合、それはバッファに変換され、ネイティブ層に送られてディスクに書き込まれます。文字列を書くときには、バッファを埋めることはありません。だから、もしあなたが
write("a")
write("b")
write("c")
していますね。
fs.write(new Buffer("a"))
fs.write(new Buffer("b"))
fs.write(new Buffer("c"))
これはI/Oレイヤーへの*3回の呼び出しです。バッファ」を使用していますが、データはバッファリングされていません。バッファード・ストリームであれば、fs.write(new Buffer ("abc"))
となり、I/Oレイヤーへの呼び出しは1回です。
現在のところ、Node.js v0.12(2015年2月6日発表の安定版)では、2つの関数をサポートしています。
cork()
と
cork()
です。これらの関数を使うことで、ようやくwriteコールのバッファリング/フラッシュができるようになるようです。
例えば、Javaにはバッファードストリームを提供するクラスがあります(BufferedOutputStream
, BufferedWriter
...)。3バイト書いた場合、3バイトのためだけにI/Oコールを行うのではなく、これらのバイトはバッファ(メモリ)に格納されます。バッファがいっぱいになると、内容がフラッシュされ、ディスクに保存されます。これにより、パフォーマンスが向上します。
私は何かを発見したわけではなく、ディスクアクセスがどのように行われるべきかを思い出しただけです。
もちろん、もう少し高度にすることもできます。ノンブロッキングで、ファイル全体を一度に書き込まず、少しずつ書き込んでいく。
var fs = require('fs');
var stream = fs.createWriteStream("my_file.txt");
stream.once('open', function(fd) {
stream.write("My first row\n");
stream.write("My second row\n");
stream.end();
});