1466 votes

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

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

72 votes

Les opérations synchrones sont idéales pour effectuer des opérations ponctuelles sur des fichiers/répertoires avant de renvoyer un module. Par exemple, l'amorçage d'un fichier de configuration.

1 votes

@PaulDraper avec un cachet chaud n'est pas vrai dans tous les cas.

22 votes

Quelles que soient les performances, il arrive parfois que l'on veuille l'exécuter de manière synchronisée pour l'expérience du développeur. Par exemple, si vous utilisez Node pour un script de traitement de données qui, par conception, devrait être bloquant, dans ce cas, l'asynchronisme est nécessaire. exists ne fait qu'ajouter des rappels inutiles.

2612voto

T.J. Crowder Points 285826

La réponse à cette question a évolué au fil des ans. Le site actuel est ici en haut, suivie des différentes réponses au fil des ans par ordre chronologique :

Réponse actuelle

Vous pouvez utiliser fs.existsSync() :

const fs = require("fs"); // Or `import fs from "fs";` with ESM
if (fs.existsSync(path)) {
    // Do something
}

Il a été déprécié pendant plusieurs années, mais ne l'est plus. Extrait de la documentation :

Notez que fs.exists() est déprécié, mais fs.existsSync() ne l'est pas. (Le paramètre paramètre de rappel de fs.exists() accepte des paramètres qui sont incompatibles avec d'autres callbacks Node.js. fs.existsSync() n'est pas utilise pas de callback).

Vous avez spécifiquement demandé un synchrone mais si vous pouvez utiliser un asynchrone à la place (c'est généralement mieux avec les E/S), utilisez fs.promises.access si vous utilisez async fonctions ou fs.access (depuis exists est déprécié ) sinon :

Dans un async fonction :

try {
    await fs.promises.access("somefile");
    // The check succeeded
} catch (error) {
    // The check failed
}

Ou avec un rappel :

fs.access("somefile", error => {
    if (!error) {
        // The check succeeded
    } else {
        // The check failed
    }
});

Réponses historiques

Voici les réponses historiques par ordre chronologique :

  • Réponse originale de 2010
    ( stat / statSync o lstat / lstatSync )
  • Mise à jour de 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 o lstat / lstatSync )
  • Mise à jour de 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 ; la documentation pour fs.stat recommande d'utiliser fs.access si vous devez vérifier l'existence sans ouvrir)
  • Mise à jour de décembre 2016
    fs.exists() est toujours déprécié mais fs.existsSync() n'est plus déprécié. Vous pouvez donc l'utiliser en toute sécurité.

Réponse originale de 2010 :

Vous pouvez utiliser statSync o lstatSync ( lien docs ), qui vous donnent 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. Donc 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 si oui, si c'est un fichier ou 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ère, etc :

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 la même manière, si c'est un fichier, il y a isFile Si c'est un dispositif de bloc, il y a isBlockDevice etc., etc. Notez le 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 vous voulez seulement savoir s'il existe, vous pouvez utiliser path.existsSync (ou avec le dernier, fs.existsSync ) comme noté par l'utilisateur618408 :

~~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 cette chose, juste qu'elle est là. path.existsSync a été déprécié il y a longtemps.


Note complémentaire : Vous avez expressément demandé comment vérifier de manière synchrone J'ai donc utilisé le xyzSync des versions des fonctions ci-dessus. Mais dans la mesure du possible, avec les E/S, il est vraiment préférable d'éviter les appels synchrones. Les appels au sous-système d'E/S prennent beaucoup de temps du point de vue de l'unité centrale. Notez combien il est facile d'appeler lstat plutôt que lstatSync :

// Is it a directory?
lstat('/the/path', function(err, stats) {
    if (!err && stats.isDirectory()) {
        // Yes it is
    }
});

Mais si vous avez besoin de la version synchrone, elle est là.

Mise à jour de septembre 2012

La réponse ci-dessous, qui date d'il y a quelques années, est maintenant un peu dépassée. La méthode actuelle consiste à utiliser fs.existsSync pour faire une vérification synchrone de l'existence des fichiers/répertoires (ou bien sûr fs.exists pour une vérification asynchrone), plutôt que la méthode path versions ci-dessous.

Ejemplo:

var fs = require('fs');

if (fs.existsSync(path)) {
    // Do something
}

// Or

fs.exists(path, function(exists) {
    if (exists) {
        // Do something
    }
});

Mise à jour février 2015

Et nous voici en 2015 et les documents de Node disent maintenant que fs.existsSync (et fs.exists ) "sera déprécié". (Parce que les gens de Node pensent qu'il est stupide de vérifier si quelque chose existe avant de l'ouvrir, ce qui est le cas ; mais ce n'est pas la seule raison de vérifier si quelque chose existe).

Donc nous sommes probablement de retour aux diverses stat des méthodes... Jusqu'à ce que cela change à nouveau, bien sûr.

Mise à jour de décembre 2015

Je ne sais pas depuis combien de temps c'est là, mais il y a aussi fs.access(path, fs.F_OK, ...) / fs.accessSync(path, fs.F_OK) . Et au moins à partir d'octobre 2016, le fs.stat documentation recommande d'utiliser fs.access pour effectuer des contrôles d'existence ( "Pour vérifier si un fichier existe sans le manipuler par la suite, fs.access() est recommandé." ). Mais notez que l'accès n'étant pas disponible est considéré comme une erreur Il est donc préférable de procéder ainsi si vous souhaitez que le fichier soit accessible :

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

Mise à jour de décembre 2016

Vous pouvez utiliser fs.existsSync() :

if (fs.existsSync(path)) {
    // Do something
}

Il a été déprécié pendant plusieurs années, mais ne l'est plus. Extrait de la documentation :

Notez que fs.exists() est déprécié, mais fs.existsSync() ne l'est pas. (Le paramètre paramètre de rappel de fs.exists() accepte des paramètres qui sont incompatibles avec d'autres callbacks Node.js. fs.existsSync() n'utilise pas utilise pas de callback).

0 votes

Vous pouvez créer un lien vers les fonctions dans la documentation. Dans les navigateurs WebKit (Safari dans mon cas), faites un clic droit et sélectionnez "Inspecter l'élément", puis trouvez dans le code HTML l'attribut "id" de la fonction vers laquelle vous voulez pointer. Dans ce cas, il s'agit de nodejs.org/docs/v0.2.5/api.html#fs-statsync-114

0 votes

@ohmantics : C'est étrange, je pensais que je l'avais fait. exactement (jusqu'à l'utilisation d'un navigateur WebKit pour trouver l'ID de l'élément :-) ) et cela n'a pas fonctionné. Mais votre lien fonctionne, donc manifestement non. (Même l'ancre est la même que celle trouvée ! Bizarre).

2 votes

@Jesse : exists ne vous dit pas s'il s'agit d'un répertoire, il peut s'agir d'un fichier, d'un tube ou d'un autre objet du système de fichiers. Et sûrement pas "grossièrement" trop compliqué ? existsSync ne remplacerait que le lstatSync le reste est juste pour montrer comment cela fonctionnerait dans une boucle. (Je ne sais pas trop pourquoi j'ai pensé que c'était nécessaire, cependant).

137voto

Jeff Points 781

En regardant la source, il y a une version synchrone de path.exists - path.existsSync . On dirait que ça a été oublié dans la documentation.

Mise à jour :

path.exists y path.existsSync sont maintenant déprécié . Veuillez utiliser fs.exists y fs.existsSync .

Mise à jour 2016 :

fs.exists et fs.existsSync ont également a été déprécié . Utilisez fs.stat() o fs.access() à la place.

Mise à jour 2019 :

utilice fs.existsSync . Il n'est pas déprécié. https://nodejs.org/api/fs.html#fs_fs_existssync_path

1 votes

Path.existsSync(p) est dans la docs 0.4.10 nodejs.org/docs/v0.4.10/api/path.html

24 votes

En fait, une réponse plus récente : path.existsSync est déprécié. Il s'appelle maintenant fs.existsSync .

9 votes

Maintenant les docs disent que fs.exists sera déprécié. nodejs.org/api/fs.html#fs_fs_existssync_path

63voto

BobDickinson Points 1588

En utilisant les API actuellement recommandées (depuis 2015) (selon les docs de 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 au problème EPERM soulevé par @broadband dans les commentaires, cela soulève un bon point. fileExists() n'est probablement pas une bonne façon de penser à ce sujet dans de nombreux cas, parce que 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 de permissions. L'erreur de permissions n'implique pas nécessairement que le fichier existe, car vous pouvez ne pas avoir les droits d'accès au répertoire contenant le fichier sur lequel vous vérifiez. Et bien sûr, il est possible que vous rencontriez une autre erreur en vérifiant l'existence du fichier.

Ainsi, mon code ci-dessus est en réalité doesFileExistAndDoIHaveAccessToIt(), mais votre question pourrait être doesFileNotExistAndCouldICreateIt(), qui serait une logique complètement différente (qui devrait tenir compte d'une erreur EPERM, entre autres choses).

Bien que la réponse fs.existsSync réponde directement à la question posée ici, ce n'est souvent pas ce que vous voulez (vous ne voulez pas seulement savoir si "quelque chose" existe à 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 l'existence d'un fichier, vous le faites probablement parce que vous avez l'intention d'entreprendre une action en fonction du résultat, et cette logique (la vérification et/ou l'action ultérieure) doit tenir compte du fait qu'une chose trouvée à ce chemin peut être un fichier ou un répertoire, et que vous pouvez rencontrer des erreurs EPERM ou autres dans le processus de vérification.

4 votes

Bien, j'ai ajouté || isDirectory() pour en faire un vérificateur de fichiers/dossiers. var stats = fs.statSync(filePath);return stats.isFile() || stats.isDirectory() ;

4 votes

Si le programme n'a pas les droits d'accès au fichier, il renvoie toujours un message faux même si le fichier existe, par exemple en supprimant tous les droits du fichier chmod ugo-rwx file.txt ou en faisant un clic droit dans Windows ... Message d'exception : Exception fs.statSync (./f.txt) : Error : EPERM : opération non autorisée, stat ' X:\f.txt '. Ce cas n'est donc pas couvert par le code supérieur.

2 votes

Wow, JS est retardé parfois. Donc, bien sûr, 97% du temps vous utiliserez le fichier, mais ne pas avoir un simple file.exists() util pour les 3% et au lieu de cela nous forcer à envelopper cela dans un try catch ? Soyez réaliste... La salope du jour.

24voto

Melbourne2991 Points 1100

Une autre mise à jour

Ayant besoin d'une réponse à cette question moi-même, j'ai consulté la documentation sur les nœuds, il semble que vous devriez no n'utilisez pas fs.exists, mais plutôt fs.open et utilisez la sortie d'erreur pour détecter si un fichier n'existe pas :

de la documentation :

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 l'existence d'un fichier avant de l'ouvrir est une méthode d'évaluation de l'efficacité du système. anti-modèle qui vous rend vulnérable aux conditions de course : un autre un autre processus peut supprimer le fichier entre les appels à fs.exists() et à fs.open(). Ouvrez simplement le fichier et gérez l'erreur quand il n'est pas n'est pas là.

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

1 votes

Existe-t-il un moyen de le faire avec openSync, plutôt qu'avec open

1 votes

@GregHornby J'imagine que cela devrait fonctionner de la même manière avec openSync.

2 votes

Pour ceux qui ont encore besoin exists et existsSync J'ai créé is-there .

14voto

broadband Points 521

J'utilise la fonction ci-dessous pour tester si le fichier existe. Elle attrape aussi d'autres exceptions. Ainsi, au cas où il y aurait des problèmes de droits, par ex. chmod ugo-rwx filename ou dans Windows Right Click -> Properties -> Security -> Advanced -> Permission entries: empty list .. retourne 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 type d'exception.

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 sur les erreurs de nodejs au 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 les droits sur le fichier, mais qu'il existe :

{
  [Error: EPERM: operation not permitted, stat 'X:\file.txt']
  errno: -4048,
  code: 'EPERM',
  syscall: 'stat',
  path: 'X:\\file.txt'
}

2 votes

J'aime beaucoup cette réponse, c'est l'une des rares qui soit à jour depuis que node a rendu obsolètes les 37 dernières façons de faire.

0 votes

Bah, tu m'as devancé. J'aurais pu gagner du temps si j'avais lu ceci.

0 votes

Très utile ! Merci

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X