ファイルまたはディレクトリが存在するかどうかをnode.jsを使用して同期的に確認するにはどうすればよいですか?
exists
は不要なコールバックを追加するだけです。
ファイルまたはディレクトリが存在するかどうかをnode.jsを使用して同期的に確認するにはどうすればよいですか?
exists
は不要なコールバックを追加するだけです。
回答:
この質問への答えは、長年にわたって変化しました。現在答えは、時系列順に長年にわたって様々な答えが続き、最上部にここにあります:
使用できますfs.existsSync()
:
const fs = require("fs"); // Or `import fs from "fs";` with ESM
if (fs.existsSync(path)) {
// Do something
}
それは数年間廃止されましたが、現在は廃止されていません。ドキュメントから:
注
fs.exists()
非推奨されますが、fs.existsSync()
ではありません。(fs.exists()
他のNode.jsコールバックと矛盾するパラメーターを受け入れるためのコールバックパラメーター。コールバックfs.existsSync()
は使用しません。)
特に同期チェックを要求しましたが、代わりに非同期チェックを使用できる場合(通常はI / Oで最適)、関数を使用しているfs.promises.access
場合、async
またはfs.access
(非推奨であるためexists
))使用していない場合:
ではasync
機能:
try {
await fs.promises.access("somefile");
// The check succeeded
} catch (error) {
// The check failed
}
またはコールバックで:
fs.access("somefile", error => {
if (!error) {
// The check succeeded
} else {
// The check failed
}
});
時系列での歴史的な答えは次のとおりです。
stat
/ statSync
またはlstat
/lstatSync
)exists
/existsSync
)exists
/の廃止が差し迫っていることexistsSync
に注意して、おそらくstat
/ statSync
またはlstat
/lstatSync
)fs.access(path, fs.F_OK, function(){})
/ もありfs.accessSync(path, fs.F_OK)
ますが、ファイル/ディレクトリが存在しない場合はエラーです。開くことなく存在を確認する必要がある場合にfs.stat
使用fs.access
することをお勧めします)fs.exists()
は引き続き非推奨ですが、非推奨でfs.existsSync()
はなくなりました。安全に使用できるようになりました。statSync
またはlstatSync
(ドキュメントリンク)を使用して、fs.Stats
オブジェクトを取得できます。一般に、関数の同期バージョンが使用可能な場合、関数の名前は非同期バージョンと同じ名前になりSync
、最後に付きます。だから、statSync
の同期バージョンですstat
。lstatSync
の同期バージョンlstat
などです。
lstatSync
何かが存在するかどうか、また存在する場合はファイルかディレクトリか(または一部のファイルシステムでは、シンボリックリンク、ブロックデバイス、キャラクターデバイスなど)の両方を通知します。たとえば、存在しているかどうかを知る必要がある場合ディレクトリ:
var fs = require('fs');
try {
// Query the entry
stats = fs.lstatSync('/the/path');
// Is it a directory?
if (stats.isDirectory()) {
// Yes it is
}
}
catch (e) {
// ...
}
...そして同様に、それがファイルの場合はisFile
、ブロックデバイスの場合isBlockDevice
、などがあります。try/catch
ます。エントリがまったく存在しない場合は、エラーがスローされます。
エントリが何であるかを気にせず、それが存在するかどうかを知りたいだけの場合は、user618408によって指摘されているようにpath.existsSync
(またはlatestでfs.existsSync
)使用できます。
var path = require('path');
if (path.existsSync("/the/path")) { // or fs.existsSync
// ...
}
aは必要ありませんが try/catch
、物があるかどうかについての情報はありません。path.existsSync
ずっと前に廃止されました。
補足:同期的にチェックする方法を明確に尋ねたのでxyzSync
、上記の関数のバージョンを使用しました。ただし、I / Oを使用する場合は、可能な限り同期呼び出しを回避するのが最善です。I / Oサブシステムへの呼び出しには、CPUの観点からかなりの時間がかかります。呼び出すのlstat
ではなく、呼び出しがいかに簡単であるかに注意してくださいlstatSync
。
// Is it a directory?
lstat('/the/path', function(err, stats) {
if (!err && stats.isDirectory()) {
// Yes it is
}
});
しかし、同期バージョンが必要な場合は、そこにあります。
数年前の以下の回答は少し古くなっています。現在の方法はfs.existsSync
、ファイル/ディレクトリの存在を同期チェックする(またはもちろん fs.exists
非同期チェックを行う)ではなく、path
以下バージョン。
例:
var fs = require('fs');
if (fs.existsSync(path)) {
// Do something
}
// Or
fs.exists(path, function(exists) {
if (exists) {
// Do something
}
});
そしてここに私たちは2015年にいて、Nodeドキュメントは今それを言っていますfs.existsSync
(そしてfs.exists
)「廃止される」とます。(Nodeの人々は、開く前に何かが存在するかどうかを確認するのは馬鹿げていると思うので、それはそうです。しかし、それが何かが存在するかどうかを確認する唯一の理由ではありません!)
ですから、私たちはおそらくさまざまなstat
方法に戻っています...もちろん、これが再び変わるまでは/もちろんです。
そこにどれくらいの時間があったかわからないが、fs.access(path, fs.F_OK, ...)
/fs.accessSync(path, fs.F_OK)
もある。そして、少なくとも2016年10月現在、このfs.stat
ドキュメントでは、を使用fs.access
して存在チェックを行うことを推奨しています(「後でファイルを操作せずにファイルが存在するかどうかをチェックすることをfs.access()
お勧めします。」)。ただし、アクセスできないことはエラーと見なされるため、ファイルにアクセスできることを期待している場合は、おそらくこれが最善です。
var fs = require('fs');
try {
fs.accessSync(path, fs.F_OK);
// Do something
} catch (e) {
// It isn't accessible
}
// Or
fs.access(path, fs.F_OK, function(err) {
if (!err) {
// Do something
} else {
// It isn't accessible
}
});
使用できますfs.existsSync()
:
if (fs.existsSync(path)) {
// Do something
}
それは数年間廃止されましたが、現在は廃止されていません。ドキュメントから:
注
fs.exists()
非推奨されますが、fs.existsSync()
ではありません。(fs.exists()
他のNode.jsコールバックと矛盾するパラメーターを受け入れるためのコールバックパラメーター。コールバックfs.existsSync()
は使用しません。)
open
呼び出しを発行して例外を処理するか、ファイルが存在しない場合は何でも処理することをお勧めします。見つかりました。結局のところ、現実の世界は無秩序です。最初に確認してそこにあるとしても、それを開こうとしたときにまだそこにあるわけではありません。最初に確認してもそこにない場合でも、それがすぐになくなるわけではありません。このようなタイミングはエッジケースのように見えますが、常に発生します。したがって、開く場合は、最初にチェックしても意味がありません。
ソースを見ると、同期バージョンのpath.exists
-がありpath.existsSync
ます。ドキュメントで見逃されたようです。
path.exists
そしてpath.existsSync
今されている非推奨。使用してください。fs.exists
とfs.existsSync
fs.exists
そして 非難されました。代わりにfs.stat()またはfs.access()を使用してください。fs.existsSync
また
使用しますfs.existsSync
。非推奨ではありません。
https://nodejs.org/api/fs.html#fs_fs_existssync_path
fs.existsSync
ます。
exists
:機能is-there
fs.exists
非推奨としてのみラベル付けされてfs.existsSync
いますが、そうではありません!
(ノードのドキュメントごとに)現在推奨されている(2015年の)APIを使用して、これは私が行うことです:
var fs = require('fs');
function fileExists(filePath)
{
try
{
return fs.statSync(filePath).isFile();
}
catch (err)
{
return false;
}
}
コメントで@broadbandによって提起されたEPERM問題に対応して、それは良い点をもたらします。fileExists()はブール値の戻りを実際に約束できないため、fileExists()はおそらく多くの場合、これについて考える良い方法ではありません。ファイルが存在するか存在しないかを明確に判断できる場合がありますが、アクセス権エラーが発生する場合もあります。確認するファイルを含むディレクトリへのアクセス許可が不足している可能性があるため、アクセス許可エラーは必ずしもファイルが存在することを意味するわけではありません。もちろん、ファイルの存在を確認する際に他のエラーが発生する可能性もあります。
したがって、上のコードは本当にdoesFileExistAndDoIHaveAccessToIt()ですが、質問はdoesFileNotExistAndCouldICreateIt()かもしれません。これは完全に異なるロジック(特にEPERMエラーを説明する必要がある)です。
fs.existsSync回答は、ここで直接尋ねられた質問に対処しますが、それはしばしばあなたが望むものではありません(「何か」がパスに存在するかどうかを知りたいだけではなく、おそらく「もの」が存在するのはファイルまたはディレクトリです)。
肝心な点は、ファイルが存在するかどうかを確認する場合、結果に基づいて何らかのアクションを実行するつもりであり、そのロジック(チェックおよび/または後続のアクション)がアイデアに対応する必要があるためです。そのパスで見つかったものがファイルまたはディレクトリである可能性があること、およびチェックの過程でEPERMまたはその他のエラーが発生する可能性があること。
file.exists()
、3%の単純なユーティリティがなく、代わりにこれをトライキャッチでラップする必要がありますか?本当のことを...今日のビッチ。
別のアップデート
私自身、ノードのドキュメントを調べて、この質問への回答が必要です。 場合、fs.existsを使用なく、代わりにfs.openを使用して、出力されたエラーを使用して、ファイルが存在しないかどうかを検出します。
ドキュメントから:
fs.exists()は時代遅れであり、歴史的な理由でのみ存在します。独自のコードで使用する理由はほとんどありません。
特に、開く前にファイルが存在するかどうかを確認することは、競合状態に対して脆弱なアンチパターンであり、別のプロセスがfs.exists()とfs.open()の呼び出しの間にファイルを削除する可能性があります。ファイルを開いて、そこにないときにエラーを処理するだけです。
以下の関数を使用して、ファイルが存在するかどうかをテストします。他の例外もキャッチします。したがって、たとえばchmod ugo-rwx filename
Windowsで権利の問題がある場合、
Right Click -> Properties -> Security -> Advanced -> Permission entries: empty list ..
関数は例外を返すはずです。ファイルは存在しますが、それにアクセスする権限がありません。この種の例外を無視するのは間違っています。
function fileExists(path) {
try {
return fs.statSync(path).isFile();
}
catch (e) {
if (e.code == 'ENOENT') { // no such file or directory. File really does not exist
console.log("File does not exist.");
return false;
}
console.log("Exception fs.statSync (" + path + "): " + e);
throw e; // something else went wrong, we don't have rights, ...
}
}
例外出力、ファイルが存在しない場合のnodejsエラードキュメント:
{
[Error: ENOENT: no such file or directory, stat 'X:\\delsdfsdf.txt']
errno: -4058,
code: 'ENOENT',
syscall: 'stat',
path: 'X:\\delsdfsdf.txt'
}
ファイルに対する権限を持っていないが存在する場合の例外:
{
[Error: EPERM: operation not permitted, stat 'X:\file.txt']
errno: -4048,
code: 'EPERM',
syscall: 'stat',
path: 'X:\\file.txt'
}
fs.exists()は非推奨です https://nodejs.org/api/fs.html#fs_fs_exists_path_callback
これで使用されるコアのnodejsの方法を実装できます:https : //github.com/nodejs/node-v0.x-archive/blob/master/lib/module.js#L86
function statPath(path) {
try {
return fs.statSync(path);
} catch (ex) {}
return false;
}
これはstatsオブジェクトを返し、statsオブジェクトを取得したら、試すことができます
var exist = statPath('/path/to/your/file.js');
if(exist && exist.isFile()) {
// do something
}
ここでいくつかの回答はそれfs.exists
を言い、fs.existsSync
両方とも非推奨です。ドキュメントによると、これは真実ではありません。fs.exists
今は欠けているだけです:
fs.exists()は非推奨ですが、fs.existsSync()は非推奨です。(fs.exists()へのコールバックパラメータは、他のNode.jsコールバックと矛盾するパラメータを受け入れます。fs.existsSync()はコールバックを使用しません。)
したがって、fs.existsSync()を安全に使用して、ファイルが存在するかどうかを同期的にチェックできます。
path
モジュールは、同期のバージョン提供していないpath.exists
あなたと周りだまして持っているので、fs
モジュールを。
私が想像できる最も速いことはfs.realpathSync
、あなたがキャッチしなければならないエラーを投げるので、try / catchであなた自身のラッパー関数を作る必要があるということです。
fileSystem(fs)テストを使用すると、エラーオブジェクトがトリガーされます。エラーオブジェクトは、try / catchステートメントでラップする必要があります。少し手間を省いて、0.4.xブランチで紹介されている機能を使用してください。
var path = require('path');
var dirs = ['one', 'two', 'three'];
dirs.map(function(dir) {
path.exists(dir, function(exists) {
var message = (exists) ? dir + ': is a directory' : dir + ': is not a directory';
console.log(message);
});
});
上のドキュメントfs.stat()
は使用するように言いますfs.access()
、ファイルを操作しない場合ようにいます。それは正当化を与えませんでした、より速いか少ない記憶の使用かもしれません?
私は線形自動化にノードを使用しているので、ファイルの存在をテストするために使用する関数を共有すると思いました。
var fs = require("fs");
function exists(path){
//Remember file access time will slow your program.
try{
fs.accessSync(path);
} catch (err){
return false;
}
return true;
}
それが質問に直接答えないことを「正しく」指摘する人々のための更新された回答は、より多くの代替オプションをもたらします。
fs.existsSync('filePath')
こちらのドキュメントもご覧ください。
パスが存在する場合はtrueを返し、それ以外の場合はfalseを返します。
非同期コンテキストでは、await
キーワードを使用して、非同期バージョンの同期メソッドを記述するだけです。単純に非同期コールバックメソッドを次のようなpromiseに変換できます。
function fileExists(path){
return new Promise((resolve, fail) => fs.access(path, fs.constants.F_OK,
(err, result) => err ? fail(err) : resolve(result))
//F_OK checks if file is visible, is default does no need to be specified.
}
async function doSomething() {
var exists = await fileExists('filePath');
if(exists){
console.log('file exists');
}
}
access()に関するドキュメント。
function asyncFileExists(path) { //F_OK checks if file is visible, is default does no need to be specified. return new Promise(function (res, rej) { fs.access( path, fs.constants.F_OK, function (err) { err ? rej(err) : res(true); }, ); }); }
おそらく、ファイルが存在するかどうかを知りたい場合は、存在する場合にそれを要求することを計画しています。
function getFile(path){
try{
return require(path);
}catch(e){
return false;
}
}
これは、このための簡単なラッパーソリューションです。
var fs = require('fs')
function getFileRealPath(s){
try {return fs.realpathSync(s);} catch(e){return false;}
}
使用法:
例:
var realPath,pathToCheck='<your_dir_or_file>'
if( (realPath=getFileRealPath(pathToCheck)) === false){
console.log('file/dir not found: '+pathToCheck);
} else {
console.log('file/dir exists: '+realPath);
}
===演算子を使用して、戻り値がfalseかどうかをテストしてください。fs.realpathSync()が適切な動作条件下でfalseを返す論理的な理由はないので、これは100%動作するはずです。
エラーが発生せず、結果としてパフォーマンスが低下しないソリューションが欲しいです。APIの観点から見ると、fs.exists()は最もエレガントなソリューションのようです。
回答から、これに対する公式のAPIサポートはないようです(直接および明示的なチェックのように)。答えの多くはstatを使用するように言っていますが、厳密ではありません。たとえば、statによってスローされたエラーが何かが存在しないことを意味するとは想定できません。
存在しないもので試してみましょう:
$ node -e 'require("fs").stat("god",err=>console.log(err))'
{ Error: ENOENT: no such file or directory, stat 'god' errno: -2, code: 'ENOENT', syscall: 'stat', path: 'god' }
存在しているがアクセスできないもので試してみましょう:
$ mkdir -p fsm/appendage && sudo chmod 0 fsm
$ node -e 'require("fs").stat("fsm/appendage",err=>console.log(err))'
{ Error: EACCES: permission denied, stat 'access/access' errno: -13, code: 'EACCES', syscall: 'stat', path: 'fsm/appendage' }
少なくとも、次のものが必要です。
let dir_exists = async path => {
let stat;
try {
stat = await (new Promise(
(resolve, reject) => require('fs').stat(path,
(err, result) => err ? reject(err) : resolve(result))
));
}
catch(e) {
if(e.code === 'ENOENT') return false;
throw e;
}
if(!stat.isDirectory())
throw new Error('Not a directory.');
return true;
};
実際に同期したいのか、それともまるで同期しているように書いて欲しいのか、という質問は明確ではありません。この例では、await / asyncを使用して、同期的にのみ書き込まれ、非同期的に実行されるようにします。
つまり、トップレベルでそれを呼び出す必要があります。
(async () => {
try {
console.log(await dir_exists('god'));
console.log(await dir_exists('fsm/appendage'));
}
catch(e) {
console.log(e);
}
})();
もう1つの方法は、必要に応じて、非同期呼び出しから返されたpromiseで.thenと.catchを使用することです。
何かが存在するかどうかを確認する場合は、それがディレクトリやファイルなどの適切なタイプであることを確認することもお勧めします。これは例に含まれています。シンボリックリンクにすることが許可されていない場合は、statが自動的にリンクをトラバースするため、statではなくlstatを使用する必要があります。
すべての非同期を置き換えて、ここでコードを同期し、代わりにstatSyncを使用できます。ただし、非同期で待機すると普遍的にサポートされるようになると予想されます。同期呼び出しは最終的には冗長になるため、減価償却されます。