node.jsを使用して、ファイルまたはディレクトリが存在するかどうかを同期的に確認するにはどうすればよいですか?
18 に答える
この質問に対する答えは、何年にもわたって変わってきました。現在の回答が一番上にあり、その後に時系列で何年にもわたるさまざまな回答が続きます。
現在の回答
あなたが使用することができます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
}
});
歴史的回答
時系列での過去の回答は次のとおりです。
- 2010年の元の回答
(stat
/statSync
またはlstat
/lstatSync
) - 2012年9月更新
(exists
/existsSync
) - 2015年2月の更新
( /
の非推奨が差し迫っていることに注意して、おそらく/または/に戻っています)exists
existsSync
stat
statSync
lstat
lstatSync
- 2015年12月の更新
(/もありfs.access(path, fs.F_OK, function(){})
ますfs.accessSync(path, fs.F_OK)
が、ファイル/ディレクトリが存在しない場合はエラーであることに注意してください。開かずに存在を確認する必要がある場合は、ドキュメントをfs.stat
使用することをお勧めします)fs.access
- 2016年12月の更新
fs.exists()
はまだ非推奨ですが、非推奨でfs.existsSync()
はなくなりました。これで安全に使用できます。
2010年からの元の回答:
statSync
またはlstatSync
(docs link)を使用して、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
ます。;に注意してください。エントリがまったく存在しない場合はエラーがスローされます。
エントリが何であるかを気にせず、エントリが存在するかどうかだけを知りたい場合は、user618408path.existsSync
が示すように(または最新のfs.existsSync
)を使用できます。
var path = require('path');
if (path.existsSync("/the/path")) { // or fs.existsSync
// ...
}
それは必要ではありませんが、 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
}
});
しかし、同期バージョンが必要な場合は、そこにあります。
2012年9月の更新
数年前の以下の回答は、現在少し古くなっています。現在の方法は、以下のバージョンではなく、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年2月の更新
そして、ここで私たちは2015年になり、Nodeのドキュメントには「非推奨になる」とfs.existsSync
書かれています。fs.exists
(ノードの人々は、何かが存在するかどうかを開く前にチェックするのは馬鹿げていると思っているので、それはそうですが、何かが存在するかどうかをチェックする理由はそれだけではありません!)
ですから、おそらくさまざまな方法に戻っていstat
ます...もちろん、これが再び変更されるまで/変更されない限り。
2015年12月の更新
どれくらいの期間そこにあるのかわかりませんが、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
}
});
2016年12月の更新
あなたが使用することができますfs.existsSync()
:
if (fs.existsSync(path)) {
// Do something
}
数年間廃止されましたが、現在は廃止されていません。ドキュメントから:
fs.exists()
は非推奨ですが、そうではないことに注意してくださいfs.existsSync()
。(fs.exists()
他のNode.jsコールバックと矛盾するパラメーターを受け入れるためのコールバックパラメーター。fs.existsSync()
コールバックを使用しません。)
path.exists
ソースを見ると、 -の同期バージョンがありpath.existsSync
ます。ドキュメントで見逃されたようです。
アップデート:
path.exists
path.existsSync
現在は非推奨です。とを使用ください。fs.exists
してfs.existsSync
2016年の更新:
fs.exists
非推奨になりました。代わりにfs.stat ()またはfs.access( )を使用してください。fs.existsSync
また、
2019年の更新:
を使用しますfs.existsSync
。非推奨ではありません。
https://nodejs.org/api/fs.html#fs_fs_existssync_path
現在推奨されている(2015年現在)API(Node docsによる)を使用して、これは私が行うことです:
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またはその他のエラーが発生する可能性があること。
別の更新
この質問への回答が必要です。ノードのドキュメントを調べましたが、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;
}
これにより、統計オブジェクトが返されます。統計オブジェクトを取得したら、試すことができます。
var exist = statPath('/path/to/your/file.js');
if(exist && exist.isFile()) {
// do something
}
const fs = require('fs');
以下のような機能をチェックインしてください。
if(fs.existsSync(<path_that_need_to_be_checked>)){
// enter the code to excecute after the folder is there.
}
else{
// Below code to create the folder, if its not there
fs.mkdir('<folder_name>', cb function);
}
ここでのいくつかの回答は、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.existsSync('filePath')
こちらのドキュメントもご覧ください。
パスが存在する場合はtrueを返し、存在しない場合はfalseを返します。
非同期Promiseソリューション
await
非同期コンテキストでは、キーワードを使用してsyncメソッドで非同期バージョンを記述できます。非同期コールバックメソッドを次のような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()に関するドキュメント。
これはすでに回答済みですが、モジュールをインストールするのが好きな場合はdtfe
、を使用できます。
ファイルは存在しますか?
const dtfe = require('dtfe');
dtfe('package.json');
//=> true
fs-extra (npm i fs-extra)とそのfs.ensureFileを使用するか、ディレクトリfs.ensureDirに使用できます。これは、fs.existsが非推奨であり、fs.accessでは、使用後にそのファイルを編集することを推奨していないためです。 fs.open()、fs.readFile()、またはfs.writeFile()を呼び出す前に、fs.access()を使用してファイルのアクセス可能性を確認します。そうすると、他のプロセスがファイルの状態を変更する可能性があるため、競合状態が発生します。代わりに、ユーザーコードはファイルを直接開いたり、読み取ったり、書き込んだりして、ファイルにアクセスできない場合に発生するエラーを処理する必要があります。」
のドキュメントには、ファイルを操作しない場合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;
}
❄️あなたは使用することができますgraph-fs
directory.exists // boolean
これに対する簡単なラッパーソリューションは次のとおりです。
var fs = require('fs')
function getFileRealPath(s){
try {return fs.realpathSync(s);} catch(e){return false;}
}
使用法:
- ディレクトリとファイルの両方で機能します
- アイテムが存在する場合は、ファイルまたはディレクトリへのパスを返します
- アイテムが存在しない場合、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);
}
必ず===演算子を使用して、returnがfalseに等しいかどうかをテストしてください。fs.realpathSync()が適切な動作条件下でfalseを返すという論理的な理由はないので、これは100%動作するはずです。
エラーが発生せず、パフォーマンスが低下しないソリューションを見たいと思います。APIの観点からは、fs.exists()は最も洗練されたソリューションのようです。
回答から、これに対する公式のAPIサポートはないようです(直接および明示的なチェックのように)。回答の多くは統計を使用すると言っていますが、厳密ではありません。たとえば、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);
}
})();
別の方法は、非同期呼び出しから返されるpromiseで.thenと.catchを使用することです(さらに下が必要な場合)。
何かが存在するかどうかを確認したい場合は、それがディレクトリやファイルなどの正しいタイプのものであることも確認することをお勧めします。これは例に含まれています。シンボリックリンクにすることが許可されていない場合は、statの代わりにlstatを使用する必要があります。これは、statがリンクを自動的にトラバースするためです。
ここですべての非同期を置き換えてコードを同期し、代わりにstatSyncを使用できます。ただし、asyncとawaitが普遍的にサポートされるようになると、Sync呼び出しは冗長になり、最終的には減価償却されることを期待してください(そうでない場合は、asyncの場合と同じように、チェーン全体でそれらを定義する必要があり、本当に無意味になります)。
ファイルが存在するかどうかを知りたい場合は、存在する場合はそれを要求することを計画している可能性があります。
function getFile(path){
try{
return require(path);
}catch(e){
return false;
}
}