Question Vérifiez de manière synchrone si le fichier / répertoire existe dans Node.js


Comment puis-je vérifier de manière synchrone node.js, si un fichier ou un répertoire existe?


825
2017-12-19 11:19


origine


Réponses:


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:

Réponse actuelle

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, mais fs.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).


Réponses historiques

Voici les réponses historiques dans l'ordre chronologique:

  • Réponse initiale de 2010
    (stat/statSync ou lstat/lstatSync)
  • Mise à jour septembre 2012
    (exists/existsSync)
  • Mise à jour février 2015
    (Notant la dépréciation imminente de exists/existsSync, donc nous sommes probablement de retour à stat/statSync ou lstat/lstatSync)
  • Mise à jour décembre 2015
    (Il y a aussi 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)
  • Mise à jour décembre 2016
    fs.exists() est encore obsolète mais fs.existsSync() n'est plus obsolète. Vous pouvez donc l'utiliser en toute sécurité maintenant.

Réponse originale de 2010:

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à.


1613
2017-12-19 11:26



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.

Mettre à jour:

path.exists et path.existsSync sont maintenant déconseillé. Veuillez utiliser fs.exists et fs.existsSync.

Mise à jour 2016:

fs.exists et fs.existsSync ont aussi été déprécié. Utilisation fs.stat () ou fs.access ()au lieu.


114
2018-02-15 19:05



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.


50
2017-09-23 21:12



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à.

http://nodejs.org/api/fs.html#fs_fs_exists_path_callback


19
2018-06-07 04:13



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'
}

10
2018-01-26 14:37



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
}

4
2017-07-28 06:53



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.


4
2017-12-04 09:02



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.


2
2017-12-19 11:32



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);
  });
});

0
2018-03-26 14:01



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;
}

0
2017-11-25 20:29



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:

  • Fonctionne pour les répertoires et les fichiers
  • Si l'élément existe, il renvoie le chemin d'accès au fichier ou au répertoire
  • Si l'élément n'existe pas, il renvoie false

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.


-1
2017-08-09 19:02