Node.js vérifie si le fichier existe


143

Comment vérifier l'existence d'un fichier ?

Dans la documentation du module, fsil y a une description de la méthode fs.exists(path, callback). Mais, si je comprends bien, il vérifie l'existence de répertoires uniquement. Et j'ai besoin de vérifier le fichier !

Comment cela peut-il être fait?


3
À partir de 2018, utilisez fs.access('file', err => err ? 'does not exist' : 'exists'), voir fs.access
mb21

Réponses:


227

Pourquoi ne pas simplement essayer d'ouvrir le fichier? fs.open('YourFile', 'a', function (err, fd) { ... }) de toute façon après une minute de recherche, essayez ceci:

var path = require('path'); 

path.exists('foo.txt', function(exists) { 
  if (exists) { 
    // do something 
  } 
}); 

// or 

if (path.existsSync('foo.txt')) { 
  // do something 
} 

Pour Node.js v0.12.x et supérieur

Les deux path.existset fs.existssont obsolètes

*Éditer:

Modifié: else if(err.code == 'ENOENT')

à: else if(err.code === 'ENOENT')

Linter se plaint que le double égal ne soit pas le triple égal.

Utilisation de fs.stat:

fs.stat('foo.txt', function(err, stat) {
    if(err == null) {
        console.log('File exists');
    } else if(err.code === 'ENOENT') {
        // file does not exist
        fs.writeFile('log.txt', 'Some log\n');
    } else {
        console.log('Some other error: ', err.code);
    }
});

1
Mais, comme il s'est avéré, fs.existsfonctionne aussi. J'ai eu des problèmes avec les autorisations sur le fichier.
RomanGorbatko

11
path.existsest en fait obsolète en faveur defs.exists
Arnaud Rinquin

42
Quiconque lit ceci maintenant (Node.js v0.12.x) garde cela à l'esprit fs.existset fs.existsSyncest également obsolète. La meilleure façon de vérifier l'existence d'un fichier est fs.stat, comme indiqué ci-dessus.
Antrikshy

8
D'après la documentation de Node js, la meilleure façon de procéder si vous prévoyez d'ouvrir le fichier après avoir vérifié son existence est de l'ouvrir et de gérer les erreurs s'il n'existe pas. Parce que votre fichier pourrait être supprimé entre votre vérification d'existence et la fonction ouverte ...
newprog

6
@Antrikshy fs.existsSyncn'est plus déprécié, mais l' fs.existsest toujours.
RyanZim

52

Un moyen plus simple de le faire de manière synchrone.

if (fs.existsSync('/etc/file')) {
    console.log('Found file');
}

Le document de l'API explique comment existsSyncfonctionne:
testez si le chemin donné existe ou non en vérifiant avec le système de fichiers.


12
fs.existsSync(path)est désormais obsolète, voir nodejs.org/api/fs.html#fs_fs_existssync_path . Pour une implémentation synchrone fs.statSync(path)est conseillée, voir ma réponse.
lmeurs le

20
@Imeurs mais nodejs.org/api/fs.html#fs_fs_existssync_path disent: Notez que fs.exists () est obsolète, mais fs.existsSync () ne l'est pas.
HaveF

9
fs.existsSyncétait obsolète, mais il ne l'est plus.
RyanZim

44

Edit: Depuis le nœud, v10.0.0nous pourrions utiliserfs.promises.access(...)

Exemple de code asynchrone qui vérifie si le fichier existe:

async function checkFileExists(file) {
  return fs.promises.access(file, fs.constants.F_OK)
           .then(() => true)
           .catch(() => false)
}

Une alternative pour stat pourrait être d'utiliser le nouveau fs.access(...):

fonction de promesse courte minifiée pour vérifier:

s => new Promise(r=>fs.access(s, fs.constants.F_OK, e => r(!e)))

Exemple d'utilisation:

let checkFileExists = s => new Promise(r=>fs.access(s, fs.constants.F_OK, e => r(!e)))
checkFileExists("Some File Location")
  .then(bool => console.logfile exists: ${bool}´))

Promesse élargie façon:

// returns a promise which resolves true if file exists:
function checkFileExists(filepath){
  return new Promise((resolve, reject) => {
    fs.access(filepath, fs.constants.F_OK, error => {
      resolve(!error);
    });
  });
}

ou si vous voulez le faire de manière synchrone:

function checkFileExistsSync(filepath){
  let flag = true;
  try{
    fs.accessSync(filepath, fs.constants.F_OK);
  }catch(e){
    flag = false;
  }
  return flag;
}

1
Vote positif, c'est certainement le moyen le plus moderne (2018) de détecter si un fichier existe dans Node.js
AKMorris

1
Oui, c'est la méthode officielle recommandée pour vérifier simplement si le fichier existe et si une manipulation ultérieure n'est pas prévue. Sinon, utilisez open / write / read et gérez l'erreur. nodejs.org/api/fs.html#fs_fs_stat_path_callback
Justin

1
Dans la documentation que je trouve fs.constants.F_OKetc. Est-il également possible d'y accéder comme fs.F_OK? Bizarre. Aussi laconique, ce qui est bien.
samson

1
Pourrait essayer de le faire avec fs.promises.access(path, fs.constants.F_OK);pour en faire simplement une promesse au lieu de créer une promesse.
Jeremy Trpka

18

fs.exists(path, callback)et fs.existsSync(path)sont maintenant obsolètes, voir https://nodejs.org/api/fs.html#fs_fs_exists_path_callback et https://nodejs.org/api/fs.html#fs_fs_existssync_path .

Pour tester l'existence d'un fichier de manière synchrone, on peut utiliser ie. fs.statSync(path). Un fs.Statsobjet sera retourné si le fichier existe, voir https://nodejs.org/api/fs.html#fs_class_fs_stats , sinon une erreur est levée qui sera interceptée par l'instruction try / catch.

var fs = require('fs'),
  path = '/path/to/my/file',
  stats;

try {
  stats = fs.statSync(path);
  console.log("File exists.");
}
catch (e) {
  console.log("File does not exist.");
}

10
Le lien que vous avez fourni pour fs.existsync indique clairement qu'il n'est PAS obsolète "Notez que fs.exists () est obsolète, mais que fs.existsSync () ne l'est pas. (Le paramètre de rappel de fs.exists () accepte les paramètres incohérents avec d'autres callbacks Node.js. fs.existsSync () n'utilise pas de callback.) "
shreddish

la première réponse (du haut), qui mentionnait d'où fsvient la variable
Dmitry Korolyov

Au moment où cette réponse a été écrite, les informations étaient correctes; cependant, fs.existsSync()n'est plus obsolète.
RyanZim

12

Ancienne version avant la V6: voici la documentation

  const fs = require('fs');    
  fs.exists('/etc/passwd', (exists) => {
     console.log(exists ? 'it\'s there' : 'no passwd!');
  });
// or Sync

  if (fs.existsSync('/etc/passwd')) {
    console.log('it\'s there');
  }

METTRE À JOUR

Nouvelles versions de la V6: documentation pourfs.stat

fs.stat('/etc/passwd', function(err, stat) {
    if(err == null) {
        //Exist
    } else if(err.code == 'ENOENT') {
        // NO exist
    } 
});

1
Les deux fs.existset fs.existsSyncsont obsolètes en fonction du lien que vous avez partagé.
Andy le

existsSyncn'est pas obsolète selon ce document, peut-être l'était-il lorsque vous l'avez lu.
Darpan

11

Mode asynchrone / attente moderne (Node 12.8.x)

const fileExists = async path => !!(await fs.promises.stat(path).catch(e => false));

const main = async () => {
    console.log(await fileExists('/path/myfile.txt'));
}

main();

Nous devons utiliser fs.stat() or fs.access()parce que fs.exists(path, callback)maintenant est obsolète

Un autre bon moyen est fs-extra


7

fs.existsest obsolète depuis la version 1.0.0. Vous pouvez utiliser à la fs.statplace de cela.

var fs = require('fs');
fs.stat(path, (err, stats) => {
if ( !stats.isFile(filename) ) { // do this 
}  
else { // do this 
}});

Voici le lien vers la documentation fs.stats


stats.isFile()n'a pas besoin filename.
Wtower le

6

@Fox: bonne réponse! Voici un peu une extension avec quelques options supplémentaires. C'est ce que j'utilise récemment comme solution incontournable:

var fs = require('fs');

fs.lstat( targetPath, function (err, inodeStatus) {
  if (err) {

    // file does not exist-
    if (err.code === 'ENOENT' ) {
      console.log('No file or directory at',targetPath);
      return;
    }

    // miscellaneous error (e.g. permissions)
    console.error(err);
    return;
  }


  // Check if this is a file or directory
  var isDirectory = inodeStatus.isDirectory();


  // Get file size
  //
  // NOTE: this won't work recursively for directories-- see:
  // http://stackoverflow.com/a/7550430/486547
  //
  var sizeInBytes = inodeStatus.size;

  console.log(
    (isDirectory ? 'Folder' : 'File'),
    'at',targetPath,
    'is',sizeInBytes,'bytes.'
  );


}

PS consultez fs-extra si vous ne l'utilisez pas déjà - c'est plutôt gentil. https://github.com/jprichardson/node-fs-extra )



3

async/awaitversion utilisant à util.promisifypartir du nœud 8:

const fs = require('fs');
const { promisify } = require('util');
const stat = promisify(fs.stat);

describe('async stat', () => {
  it('should not throw if file does exist', async () => {
    try {
      const stats = await stat(path.join('path', 'to', 'existingfile.txt'));
      assert.notEqual(stats, null);
    } catch (err) {
      // shouldn't happen
    }
  });
});

describe('async stat', () => {
  it('should throw if file does not exist', async () => {
    try {
      const stats = await stat(path.join('path', 'to', 'not', 'existingfile.txt'));
    } catch (err) {
      assert.notEqual(err, null);
    }
  });
});

2
  fs.statSync(path, function(err, stat){
      if(err == null) {
          console.log('File exists');
          //code when all ok
      }else if (err.code == "ENOENT") {
        //file doesn't exist
        console.log('not file');

      }
      else {
        console.log('Some other error: ', err.code);
      }
    });

2

Après un peu d'expérimentation, j'ai trouvé que l'exemple suivant fs.statétait un bon moyen de vérifier de manière asynchrone si un fichier existe. Il vérifie également que votre "fichier" est "vraiment un fichier" (et non un répertoire).

Cette méthode utilise Promises, en supposant que vous travaillez avec une base de code asynchrone:

const fileExists = path => {
  return new Promise((resolve, reject) => {
    try {
      fs.stat(path, (error, file) => {
        if (!error && file.isFile()) {
          return resolve(true);
        }

        if (error && error.code === 'ENOENT') {
          return resolve(false);
        }
      });
    } catch (err) {
      reject(err);
    }
  });
};

Si le fichier n'existe pas, la promesse est toujours résolue, quoique false. Si le fichier existe et qu'il s'agit d'un répertoire, alors est résolu true. Toute erreur tentant de lire le fichier rejectpromettra l'erreur elle-même.


1

Eh bien, je l'ai fait de cette façon, comme on le voit sur https://nodejs.org/api/fs.html#fs_fs_access_path_mode_callback

fs.access('./settings', fs.constants.F_OK | fs.constants.R_OK | fs.constants.W_OK, function(err){
  console.log(err ? 'no access or dir doesnt exist' : 'R/W ok');

  if(err && err.code === 'ENOENT'){
    fs.mkdir('settings');
  }
});

Y a-t-il un problème avec cela?


0

autrefois, avant de m'asseoir, je vérifie toujours si la chaise est là, puis je m'assois sinon j'ai un plan alternatif comme m'asseoir sur un entraîneur. Maintenant, le site node.js suggère d'aller (pas besoin de vérifier) ​​et la réponse ressemble à ceci:

    fs.readFile( '/foo.txt', function( err, data )
    {
      if(err) 
      {
        if( err.code === 'ENOENT' )
        {
            console.log( 'File Doesn\'t Exist' );
            return;
        }
        if( err.code === 'EACCES' )
        {
            console.log( 'No Permission' );
            return;
        }       
        console.log( 'Unknown Error' );
        return;
      }
      console.log( data );
    } );

code extrait de http://fredkschott.com/post/2014/03/understanding-error-first-callbacks-in-node-js/ de mars 2014, et légèrement modifié pour s'adapter à l'ordinateur. Il vérifie également l'autorisation - supprimez l'autorisation de testerchmod a-r foo.txt


0

rappel de vannilla Nodejs

function fileExists(path, cb){
  return fs.access(path, fs.constants.F_OK,(er, result)=> cb(!err && result)) //F_OK checks if file is visible, is default does no need to be specified.
}

les documents indiquent que vous devriez utiliser access()en remplacement de obsolèteexists()

Nodejs avec build in promise (node ​​7+)

function fileExists(path, cb){
  return new Promise((accept,deny) => 
    fs.access(path, fs.constants.F_OK,(er, result)=> cb(!err && result))
  );
}

Framework javascript populaire

fs-extra

var fs = require('fs-extra')
await fs.pathExists(filepath)

Comme vous le voyez beaucoup plus simple. Et l'avantage par rapport à promisify est que vous avez des typages complets avec ce package (intellisense / typescript complet)! La plupart des cas, vous aurez déjà inclus cette bibliothèque car (+ -10.000) d'autres bibliothèques en dépendent.


0

Vous pouvez utiliser fs.statpour vérifier si la cible est un fichier ou un répertoire et vous pouvez utiliser fs.accesspour vérifier si vous pouvez écrire / lire / exécuter le fichier. (n'oubliez pas d'utiliser path.resolvepour obtenir le chemin complet de la cible)

Documentation:

Exemple complet (TypeScript)

import * as fs from 'fs';
import * as path from 'path';

const targetPath = path.resolve(process.argv[2]);

function statExists(checkPath): Promise<fs.Stats> {
  return new Promise((resolve) => {
    fs.stat(checkPath, (err, result) => {
      if (err) {
        return resolve(undefined);
      }

      return resolve(result);
    });
  });
}

function checkAccess(checkPath: string, mode: number = fs.constants.F_OK): Promise<boolean> {
  return new Promise((resolve) => {
    fs.access(checkPath, mode, (err) => {
      resolve(!err);
    });
  });
}

(async function () {
  const result = await statExists(targetPath);
  const accessResult = await checkAccess(targetPath, fs.constants.F_OK);
  const readResult = await checkAccess(targetPath, fs.constants.R_OK);
  const writeResult = await checkAccess(targetPath, fs.constants.W_OK);
  const executeResult = await checkAccess(targetPath, fs.constants.X_OK);
  const allAccessResult = await checkAccess(targetPath, fs.constants.F_OK | fs.constants.R_OK | fs.constants.W_OK | fs.constants.X_OK);

  if (result) {
    console.group('stat');
    console.log('isFile: ', result.isFile());
    console.log('isDir: ', result.isDirectory());
    console.groupEnd();
  }
  else {
    console.log('file/dir does not exist');
  }

  console.group('access');
  console.log('access:', accessResult);
  console.log('read access:', readResult);
  console.log('write access:', writeResult);
  console.log('execute access:', executeResult);
  console.log('all (combined) access:', allAccessResult);
  console.groupEnd();

  process.exit(0);
}());

0

Pour la version asynchrone! Et avec la version promise! Voici la manière simple et propre!

try {
    await fsPromise.stat(filePath);
    /**
     * File exists!
     */
    // do something
} catch (err) {
    if (err.code = 'ENOENT') {
        /**
        * File not found
        */
    } else {
        // Another error!
    }
}

Un extrait plus pratique de mon code pour mieux illustrer:


try {
    const filePath = path.join(FILES_DIR, fileName);
    await fsPromise.stat(filePath);
    /**
     * File exists!
     */
    const readStream = fs.createReadStream(
        filePath,
        {
            autoClose: true,
            start: 0
        }
    );

    return {
        success: true,
        readStream
    };
} catch (err) {
    /**
     * Mapped file doesn't exists
     */
    if (err.code = 'ENOENT') {
        return {
            err: {
                msg: 'Mapped file doesn\'t exists',
                code: EErrorCode.MappedFileNotFound
            }
        };
    } else {
        return {
            err: {
                msg: 'Mapped file failed to load! File system error',
                code: EErrorCode.MappedFileFileSystemError
            }
        }; 
   }
}

L'exemple ci-dessus est juste pour la démonstration! J'aurais pu utiliser l'événement d'erreur du flux de lecture! Pour attraper les erreurs! Et sautez les deux appels!

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.