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?
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);
}
});
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.
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;
}
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.");
}
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
}
});
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
@ 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 )
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.
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);
}
});
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.
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?
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);
}
});
});
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
function fileExists(path, cb){
return new Promise((accept,deny) =>
fs.access(path, fs.constants.F_OK,(er, result)=> cb(!err && result))
);
}
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.
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);
}());
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