Comment puis-je vérifier de manière synchrone node.js, si un fichier ou un répertoire existe?
Comment puis-je vérifier de manière synchrone node.js, si un fichier ou un répertoire existe?
La réponse à cette question a changé au fil des ans. le actuel réponse est ici en haut, suivie par les différentes réponses au fil des années dans l'ordre chronologique:
Vous pouvez utiliser fs.existsSync()
:
var fs = require('fs');
if (fs.existsSync(path)) {
// Do something
}
Il a été déprécié pendant plusieurs années, mais ne l'est plus. De la docs:
Notez que
fs.exists()
est obsolète, maisfs.existsSync()
n'est pas. (Le paramètre de rappel àfs.exists()
accepte les paramètres qui sont Incompatible avec les autres rappels Node.js.fs.existsSync()
ne fait pas utiliser un rappel.)
Vous avez spécifiquement demandé un synchrone vérifiez, mais si vous pouvez utiliser un asynchrone vérifiez à la place (généralement mieux avec E / S), utilisez fs.access
(depuis exists
est obsolète).
Voici les réponses historiques dans l'ordre chronologique:
stat
/statSync
ou lstat
/lstatSync
)exists
/existsSync
)exists
/existsSync
, donc nous sommes probablement de retour à stat
/statSync
ou lstat
/lstatSync
)fs.access(path, fs.F_OK, function(){})
/ fs.accessSync(path, fs.F_OK)
, mais notez que si le fichier / répertoire n'existe pas, c'est une erreur; docs pour fs.stat
recommande d'utiliser fs.access
si vous devez vérifier l'existence sans l'ouvrir)fs.exists()
est encore obsolète mais fs.existsSync()
n'est plus obsolète. Vous pouvez donc l'utiliser en toute sécurité maintenant.Vous pouvez utiliser statSync
ou lstatSync
(lien docs), qui vous donne un fs.Stats
objet. En général, si une version synchrone d'une fonction est disponible, elle aura le même nom que la version asynchrone avec Sync
à la fin. Alors statSync
est la version synchrone de stat
; lstatSync
est la version synchrone de lstat
, etc.
lstatSync
vous indique à la fois si quelque chose existe et, dans l'affirmative, s'il s'agit d'un fichier ou d'un répertoire (ou dans certains systèmes de fichiers, un lien symbolique, un périphérique de bloc, un périphérique de caractères, etc.), par ex. si vous avez besoin de savoir s'il existe et s'il s'agit d'un répertoire:
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) {
// ...
}
... et de même si c'est un fichier, il y a isFile
; si c'est un périphérique de bloc, il y a isBlockDevice
, etc., etc. try/catch
; il jette une erreur si l'entrée n'existe pas du tout.
Si vous ne vous souciez pas de ce que l'entrée est et ne veulent savoir si elle existe, vous pouvez utiliser path.existsSync
(ou avec le dernier, fs.existsSync
) comme noté par user618408:
var path = require('path');
if (path.existsSync("/the/path")) { // or fs.existsSync
// ...
}
Il ne nécessite pas de try/catch
, mais ne vous donne aucune information sur ce qu'est la chose, juste que c'est là.
En regardant la source, il y a une version synchrone de path.exists
- path.existsSync
. On dirait que ça a été manqué dans les docs.
path.exists
et path.existsSync
sont maintenant déconseillé. Veuillez utiliser .fs.exists
et fs.existsSync
fs.exists
et fs.existsSync ont aussi été déprécié. Utilisation fs.stat () ou fs.access ()au lieu.
En utilisant les API actuellement recommandées (à partir de 2015) (par les docs Node), voici ce que je fais:
var fs = require('fs');
function fileExists(filePath)
{
try
{
return fs.statSync(filePath).isFile();
}
catch (err)
{
return false;
}
}
En réponse à la question EPERM soulevée par @broadband dans les commentaires, cela soulève un bon point. fileExists () n'est probablement pas un bon moyen d'y penser dans de nombreux cas, car fileExists () ne peut pas vraiment promettre un retour booléen. Vous pouvez être en mesure de déterminer définitivement que le fichier existe ou n'existe pas, mais vous pouvez également obtenir une erreur d'autorisations. L'erreur d'autorisation n'implique pas nécessairement que le fichier existe, car vous pourriez manquer de l'autorisation du répertoire contenant le fichier sur lequel vous vérifiez. Et bien sûr, il y a des chances que vous rencontriez une autre erreur en vérifiant l'existence d'un fichier.
Donc, mon code ci-dessus est vraiment doesFileExistAndDoIIaveAccessToIt (), mais votre question pourrait être doesFileNotExistAndCouldICreateIt (), ce qui serait une logique complètement différente (qui aurait besoin de prendre en compte une erreur EPERM, entre autres choses).
Alors que la réponse de fs.existsSync répond directement à la question posée ici, ce n'est souvent pas ce que vous voulez (vous ne voulez pas simplement savoir si "quelque chose" existe sur un chemin, vous vous souciez probablement de savoir si la "chose" qui existe est un fichier ou un répertoire).
L'essentiel est que si vous vérifiez si un fichier existe, vous le faites probablement parce que vous avez l'intention de prendre une action basée sur le résultat, et cette logique (la vérification et / ou l'action subséquente) devrait tenir compte de l'idée qu'une chose trouvée sur ce chemin peut être un fichier ou un répertoire, et que vous pouvez rencontrer EPERM ou d'autres erreurs dans le processus de vérification.
Autre mise à jour
Ayant besoin d'une réponse à cette question moi-même j'ai regardé les docs de noeud, semble que vous devriez ne pas utilisez fs.exists, utilisez plutôt fs.open et utilisez outputted error pour détecter si un fichier n'existe pas:
à partir des docs:
fs.exists () est un anachronisme et n'existe que pour des raisons historiques. Il ne devrait presque jamais y avoir de raison de l'utiliser dans votre propre code.
En particulier, vérifier si un fichier existe avant de l'ouvrir est un anti-pattern qui vous laisse vulnérable aux conditions de course: un autre processus peut supprimer le fichier entre les appels à fs.exists () et fs.open (). Il suffit d'ouvrir le fichier et de gérer l'erreur quand ce n'est pas Là.
J'utilise la fonction ci-dessous pour tester si le fichier existe. Il attrape aussi d'autres exceptions. Donc, au cas où il y aurait des problèmes de droits, par exemple chmod ugo-rwx filename
ou dans Windows
Right Click -> Properties -> Security -> Advanced -> Permission entries: empty list ..
La fonction renvoie l'exception comme il se doit. Le fichier existe mais nous n'avons pas le droit d'y accéder. Ce serait une erreur d'ignorer ce genre d'exceptions.
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, ...
}
}
Sortie d'exception, documentation des erreurs nodejs dans le cas où le fichier n'existe pas:
{
[Error: ENOENT: no such file or directory, stat 'X:\\delsdfsdf.txt']
errno: -4058,
code: 'ENOENT',
syscall: 'stat',
path: 'X:\\delsdfsdf.txt'
}
Exception dans le cas où nous n'avons pas de droits sur le fichier, mais existe:
{
[Error: EPERM: operation not permitted, stat 'X:\file.txt']
errno: -4048,
code: 'EPERM',
syscall: 'stat',
path: 'X:\\file.txt'
}
fs.exists () est déprécié ne l'utilise pas https://nodejs.org/api/fs.html#fs_fs_exists_path_callback
Vous pouvez implémenter le noyau nodejs utilisé ici: 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;
}
cela retournera l'objet stats puis une fois que vous avez l'objet stats, vous pouvez essayer
var exist = statPath('/path/to/your/file.js');
if(exist && exist.isFile()) {
// do something
}
Certaines réponses ici dit que fs.exists
et fs.existsSync
sont tous les deux obsolètes. D'après les docs, ce n'est plus vrai. Seulement fs.exists
est déprécié maintenant:
Notez que fs.exists () est obsolète, mais que fs.existsSync () ne l'est pas. (Le paramètre de rappel à fs.exists () accepte les paramètres qui sont Incompatible avec les autres rappels Node.js. fs.existsSync () ne pas utiliser un rappel.)
Ainsi, vous pouvez utiliser en toute sécurité fs.existsSync () pour vérifier de manière synchrone si un fichier existe.
le path
module ne fournit pas une version synchrone de path.exists
donc vous devez tromper avec le fs
module.
La chose la plus rapide que je puisse imaginer est l'utilisation fs.realpathSync
qui va lancer une erreur que vous devez attraper, vous devez donc créer votre propre fonction wrapper avec un try / catch.
L'utilisation de tests systemSystem (fs) déclenchera des objets d'erreur, que vous devrez ensuite placer dans une instruction try / catch. Épargnez-vous quelques efforts et utilisez une fonction introd dans la branche 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);
});
});
Les documents sur fs.stat()
dit d'utiliser fs.access()
si vous ne manipulez pas le fichier. Il n'a pas donné une justification, pourrait être plus rapide ou moins même usage?
J'utilise un noeud pour l'automatisation linéaire, donc j'ai pensé partager la fonction que j'utilise pour tester l'existence d'un fichier.
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;
}
Voici une solution d'encapsulation simple pour cela:
var fs = require('fs')
function getFileRealPath(s){
try {return fs.realpathSync(s);} catch(e){return false;}
}
Usage:
Exemple:
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);
}
Assurez-vous que vous utilisez l'opérateur === pour tester si return vaut false. Il n'y a aucune raison logique que fs.realpathSync () renvoie false dans des conditions de travail correctes, donc je pense que cela devrait fonctionner à 100%.
Je préférerais voir une solution qui ne génère pas d'erreur et de coup de performance qui en résulte. Du point de vue de l'API, fs.exists () semble être la solution la plus élégante.