あなたの直感が正しく推測したように、exists / writeFile
呼び出しのペアを使用した単純なソリューションは間違っています。非同期コードは予測できない方法で実行されます。そして、与えられた場合、それは
- ファイルはあります
a.txt
か?- いいえ。
- (ファイル
a.txt
は別のプログラムによって作成されます)
a.txt
可能であれば書き込みます。- わかった。
しかし、はい、1 回の呼び出しでそれを行うことができます。私たちはファイル システムを扱っているので、 の開発者マニュアルを読むことをお勧めしますfs
。そしてねえ、ここに興味深い部分があります。
'w' - 書き込み用にファイルを開きます。ファイルが作成されるか (存在しない場合)、切り捨てられます (存在する場合)。
'wx' - 'w' と同様ですが、パスが存在する場合は失敗します。
したがって、あとは呼び出しに追加wx
するだけです。fs.open
でもまあ、私たちはfopen
IO のようなものは好きではありません。fs.writeFile
もう少し読み進めてみましょう。
fs.readFile(ファイル名[, オプション], コールバック)#
ファイル名 文字列
options オブジェクト
エンコーディング文字列 | Null デフォルト = null
フラグ文字列のデフォルト = 'r'
コールバック関数
それoptions.flag
は有望に見えます。だから私たちは試します
fs.writeFile(path, data, { flag: 'wx' }, function (err) {
if (err) throw err;
console.log("It's saved!");
});
そして、それは単一の書き込みに対して完全に機能します。このコードでタスクを解決しようとすると、このコードはさらに奇妙な方法で失敗すると思います。原子的な「存在を確認しa_#.jpg
、空の場合はそこに書き込む」操作がありますが、他のすべてのfs
状態はロックされておらず、a_1.jpg
既に確認している間にファイルが自然に消える場合がありますa_5.jpg
。*ほとんどのファイル システムはACIDデータベースではなく、少なくともいくつかのアトミック操作を実行できるという事実は奇跡的です。wx
コードが一部のプラットフォームで機能しない可能性が非常に高いです。したがって、あなたの正気のために、最後にデータベースを使用してください。
苦しみについてのもう少しの情報
memoize-fs
ネットワーク/CPU時間を節約するために、ファイルシステムへの関数呼び出しの結果をキャッシュするようなものを書いていると想像してください。ファイルが存在する場合は読み取り用に、存在しない場合は書き込み用に、すべて 1 回の呼び出しで開くことができますか? それらの旗を面白く見てみましょう。しばらく頭を働かせると、それが私たちの望むことを実行することがわかりa+
ます: ファイルが存在しない場合、ファイルが存在しない場合は作成され、読み取りと書き込みの両方のために開かれます。ファイルが存在する場合は、ファイルをクリアせずにw+
( )。(smth)File
しかし今では、関数でも関数でも使用できませんcreate(Smth)Stream
。そして、それは欠けている機能のようです。
アトミック非同期ファイル システム API の欠如は Node.js の欠点であるため、Node.js github への機能要求 (またはバグ) として気軽にファイルしてください。ただし、すぐに変更を期待しないでください。
編集。LinusとDan Luuの記事にリンクしたいと思います。なぜあなたは自分のfs
電話で賢いことをしたくないのかという理由についてです。