web-dev-qa-db-fra.com

Node.js vérifier le fichier existe

Comment puis-je vérifier l'existence d'un fichier ?

La documentation du module fs contient 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 je dois vérifier le fichier!

Comment cela peut-il être fait?

116
RomanGorbatko

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

path.exists et fs.exists sont obsolètes

*Modifier:

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

Un moyen plus facile de faire cela de manière synchrone. 

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

La documentation de l'API indique comment fonctionne existsSync:
Vérifie si le chemin indiqué existe ou non en vérifiant auprès du système de fichiers.

43
Paul Ho

Une alternative à stat pourrait utiliser le nouveau fs.access(...) :

fonction de promesse abrégée pour la vérification: 

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

Exemple d'utilisation:

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

manière Promise élargie:

// returns a promise which resolves true if file exists:
function checkFileExists(filepath){
  return new Promise((resolve, reject) => {
    fs.access(filepath, fs.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.F_OK);
  }catch(e){
    flag = false;
  }
  return flag;
}
33
mido

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

Pour tester l’existence simultanée d’un fichier, on peut utiliser ie. fs.statSync(path). Un objet fs.Stats sera renvoyé si le fichier existe, voir https://nodejs.org/api/fs.html#fs_class_fs_stats , sinon une erreur est renvoyée et 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.");
}
18
lmeurs

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 à partir de V6: documentation pour fs.stat

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

fs.exists est obsolète depuis 1.0.0. Vous pouvez utiliser fs.stat au lieu de cela.

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

Voici le lien pour la documentation fs.stats

7
Koushik Das

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

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.'
  );


}

P.S. consultez fs-extra si vous ne l'utilisez pas déjà - c'est très gentil . https://github.com/jprichardson/node-fs-extra )

5
mikermcneil

Il y a beaucoup de commentaires inexacts sur le fait que fs.existsSync() soit obsolète; ce n'est pas.

https://nodejs.org/api/fs.html#fs_fs_existssync_path

Notez que fs.exists () est obsolète, mais fs.existsSync () ne l’est pas.

4
chrisw
  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
D.Belda

Après quelques expériences, j'ai trouvé que l'exemple suivant utilisant 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-est-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, bien que false. Si le fichier existe et qu’il s’agit d’un répertoire, résolvons true. Toute erreur tentant de lire le fichier reject promettra l'erreur elle-même.

2
f1lt3r

Eh bien je l’ai fait de cette façon, comme indiqué 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 at-il un problème avec cela?

1
nthapa

async/await version utilisant util.promisify à partir 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);
    }
  });
});
1

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 docs dites que vous devez utiliser access() en remplacement de exists(), obsolète

Nodejs avec construit dans la promesse (nœud 7+)

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

Cadre javascript populaire

fs-extra

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

Comme vous voyez beaucoup plus simple. Et l'avantage par rapport à promisify est que vous avez des saisies complètes avec ce paquet (intellisense/TypeScript complet)! La plupart des cas, vous aurez déjà inclus cette bibliothèque car (+ -10 000) les autres bibliothèques en dépendent.

0
Joel Harkes

Modalité asynchrone/attente moderne (Node 12.8.x)

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


console.log(await fileExists('/path/myfile.txt'));

Vous pouvez utiliser fs.stat pour vérifier si cible est un fichier ou un répertoire et vous pouvez utiliser fs.access pour vérifier si vous pouvez écrire/lire/exécuter le fichier. (n'oubliez pas d'utiliser path.resolve pour 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
BrunoLM

jadis, avant de m'asseoir, je vérifiais toujours si le fauteuil était là, puis je m'asseyais, sinon j'ai un autre plan, comme s'asseoir sur un entraîneur. Maintenant, le site node.js suggère simplement 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 - supprime la permission de tester chmod a-r foo.txt

0
user2167003