Node.js comprueba si el archivo existe


143

¿Como verifico la existencia de un archivo ?

En la documentación del módulo fshay una descripción del método fs.exists(path, callback). Pero, según tengo entendido, verifica la existencia de solo directorios. ¡Y necesito revisar el archivo !

¿Cómo se puede hacer esto?


3
A partir de 2018, use fs.access('file', err => err ? 'does not exist' : 'exists'), vea fs.access
mb21

Respuestas:


227

¿Por qué no intentas abrir el archivo? fs.open('YourFile', 'a', function (err, fd) { ... }) de todos modos después de una búsqueda de un minuto intente esto:

var path = require('path'); 

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

// or 

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

Para Node.js v0.12.xy superior

Ambos path.existsy fs.existshan quedado en desuso

*Editar:

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

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

Linter se queja de que el doble igual no es el triple igual.

Usando 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
Pero, como resultó, fs.existstambién funciona. He tenido problemas con los permisos del archivo.
RomanGorbatko

11
path.existsen realidad está en desuso a favor defs.exists
Arnaud Rinquin

42
Cualquiera que lea esto ahora (Node.js v0.12.x) tenga en cuenta eso fs.existsy fs.existsSynctambién ha quedado en desuso. La mejor manera de verificar la existencia del archivo es fs.stat, como se demostró anteriormente.
Antrikshy

8
Según la documentación de Node js, parece que la mejor manera de hacerlo si planea abrir el archivo después de verificar su existencia es abrirlo y manejar los errores si no existe. Debido a que su archivo podría eliminarse entre su cheque existente y la función de abrir ...
newprog

66
@Antrikshy fs.existsSyncya no está depricada, aunque fs.existstodavía lo está.
RyanZim

52

Una forma más fácil de hacer esto sincrónicamente.

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

El documento de API dice cómo existsSyncfunciona:
pruebe si la ruta dada existe o no verificando con el sistema de archivos.


12
fs.existsSync(path)ahora está en desuso, consulte nodejs.org/api/fs.html#fs_fs_existssync_path . Para una implementación síncrona fs.statSync(path)se recomienda, vea mi respuesta.
lmeurs

20
@Imeurs pero nodejs.org/api/fs.html#fs_fs_existssync_path dicen: Tenga en cuenta que fs.exists () está en desuso, pero fs.existsSync () no.
HaveF

9
fs.existsSyncfue desaprobado, pero ya no lo es.
RyanZim

44

Editar: desde el nodo v10.0.0podríamos usarfs.promises.access(...)

Ejemplo de código asíncrono que verifica si el archivo existe:

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

Una alternativa para stat podría estar usando el nuevo fs.access(...):

Función de promesa corta minimizada para comprobar:

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

Uso de la muestra:

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

Promesa ampliada:

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

o si quieres hacerlo sincrónicamente:

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

1
Upvoted, esta es definitivamente la forma más moderna (2018) de detectar si un archivo existe en Node.js
AKMorris

1
Sí, este es el método oficial recomendado para verificar simplemente si el archivo existe y no se espera la manipulación posterior. De lo contrario, use abrir / escribir / leer y manejar el error. nodejs.org/api/fs.html#fs_fs_stat_path_callback
Justin

1
En la documentación que encuentro, fs.constants.F_OKetc. ¿También es posible acceder a ellos fs.F_OK? Extraño. También conciso, lo cual es bueno.
samson

1
Podría intentar hacerlo fs.promises.access(path, fs.constants.F_OK);simplemente para convertirlo en una Promesa en lugar de crear una Promesa.
Jeremy Trpka

18

fs.exists(path, callback)y fs.existsSync(path)ahora están en desuso, consulte https://nodejs.org/api/fs.html#fs_fs_exists_path_callback y https://nodejs.org/api/fs.html#fs_fs_existssync_path .

Para probar la existencia de un archivo sincrónicamente, se puede usar ie. fs.statSync(path). Se fs.Statsdevolverá un objeto si el archivo existe, consulte https://nodejs.org/api/fs.html#fs_class_fs_stats ; de lo contrario, se generará un error que será detectado por la instrucción 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
El enlace que proporcionó para fs.existsync claramente indica que NO está en desuso "Tenga en cuenta que fs.exists () está en desuso, pero fs.existsSync () no. (El parámetro de devolución de llamada a fs.exists () acepta parámetros que son inconsistentes con otros servicios repetidos Node.js fs.existsSync () no utiliza una devolución de llamada)"..
shreddish

la primera respuesta (desde arriba), que menciona de dónde fsproviene la variable
Dmitry Korolyov

En el momento en que se escribió esta respuesta, la información era correcta; sin embargo, fs.existsSync()ya no está en desuso.
RyanZim

12

Versión anterior a V6: aquí está la documentación

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

ACTUALIZAR

Nuevas versiones de V6: documentación parafs.stat

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

1
Ambos fs.existsy fs.existsSyncestán en desuso de acuerdo con el enlace que ha compartido.
Andy

existsSyncno está en desuso según ese documento, puede ser cuando lo leyó.
Darpan

11

Modo asíncrono / espera moderno (Nodo 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();

Necesitamos usar fs.stat() or fs.access()porque fs.exists(path, callback)ahora está en desuso

Otra buena manera es fs-extra


7

fs.existsha quedado en desuso desde 1.0.0. Puedes usar en fs.statlugar de eso.

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

Aquí está el enlace para la documentación fs.stats


stats.isFile()no necesita filename.
Wtower

6

@Fox: ¡gran respuesta! Aquí hay una pequeña extensión con algunas opciones más. Es lo que he estado usando últimamente como una solución:

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


}

PD: echa un vistazo a fs-extra si aún no lo estás usando, es bastante dulce. https://github.com/jprichardson/node-fs-extra )



3

async/awaitversión utilizando a util.promisifypartir del Nodo 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

Después de un poco de experimentación, encontré que el siguiente ejemplo fs.states una buena manera de verificar asincrónicamente si existe un archivo. También comprueba que su "archivo" es "realmente-es-un-archivo" (y no un directorio).

Este método usa Promesas, suponiendo que está trabajando con una base de código asincrónica:

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 el archivo no existe, la promesa aún se resuelve, aunque false. Si el archivo existe, y es un directorio, entonces se resuelve true. Cualquier error que intente leer el archivo rejectpromete el error mismo.


1

Bueno, lo hice de esta manera, como se ve en 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');
  }
});

hay algun problema con esto?


0

en los viejos tiempos, antes de sentarme, siempre verifico si la silla está allí, luego me siento, de lo contrario tengo un plan alternativo como sentarme en un entrenador. Ahora el sitio node.js sugiere simplemente ir (no es necesario verificar) y la respuesta se ve así:

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

código tomado de http://fredkschott.com/post/2014/03/understanding-error-first-callbacks-in-node-js/ de marzo de 2014, y ligeramente modificado para adaptarse a la computadora. Comprueba también el permiso: elimine el permiso para probarchmod a-r foo.txt


0

devolución de llamada 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.
}

los documentos dicen que deberías usar access()como reemplazo de obsoletosexists()

Nodejs con build en promesa (nodo 7+)

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

Marco javascript popular

fs-extra

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

Como veis mucho más sencillo. ¡Y la ventaja sobre promisify es que tiene tipings completos con este paquete (intellisense / mecanografiado completo)! La mayoría de los casos ya habrá incluido esta biblioteca porque (+ -10,000) otras bibliotecas dependen de ella.


0

Puede usar fs.statpara verificar si el destino es un archivo o directorio y puede fs.accessverificar si puede escribir / leer / ejecutar el archivo. (recuerde usar path.resolvepara obtener la ruta completa para el objetivo)

Documentación:

Ejemplo completo (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

¡Para la versión asincrónica! ¡Y con la versión prometedora! Aquí la forma simple y limpia!

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

Un fragmento más práctico de mi código para ilustrar mejor:


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

¡El ejemplo anterior es solo para demostración! ¡Podría haber usado el evento de error de la secuencia de lectura! Para atrapar cualquier error! ¡Y saltea las dos llamadas!

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.