¿Cómo puedo verificar sincrónicamente, usando node.js , si existe un archivo o directorio?
exists
solo agrega devoluciones de llamada innecesarias.
¿Cómo puedo verificar sincrónicamente, usando node.js , si existe un archivo o directorio?
exists
solo agrega devoluciones de llamada innecesarias.
Respuestas:
La respuesta a esta pregunta ha cambiado con los años. La respuesta actual está aquí en la parte superior, seguida de varias respuestas a lo largo de los años en orden cronológico:
Puedes usar fs.existsSync()
:
const fs = require("fs"); // Or `import fs from "fs";` with ESM
if (fs.existsSync(path)) {
// Do something
}
Fue en desuso durante varios años, pero ya no lo es. De los documentos:
Tenga en cuenta que
fs.exists()
está en desuso, perofs.existsSync()
no lo está. (El parámetro de devolución de llamada parafs.exists()
aceptar parámetros que son inconsistentes con otras devoluciones de llamada de Node.js.fs.existsSync()
No utiliza una devolución de llamada).
Ha solicitado específicamente una verificación sincrónica , pero si puede usar una verificación asincrónica en su lugar (generalmente mejor con E / S), use fs.promises.access
si está utilizando async
funciones o fs.access
(dado que exists
está en desuso ) si no:
En una async
función:
try {
await fs.promises.access("somefile");
// The check succeeded
} catch (error) {
// The check failed
}
O con una devolución de llamada:
fs.access("somefile", error => {
if (!error) {
// The check succeeded
} else {
// The check failed
}
});
Aquí están las respuestas históricas en orden cronológico:
stat
/ statSync
o lstat
/ lstatSync
)exists
/ existsSync
)exists
/ existsSync
, por lo que probablemente volvamos a stat
/ statSync
o lstat
/ lstatSync
)fs.access(path, fs.F_OK, function(){})
/ fs.accessSync(path, fs.F_OK)
, pero tenga en cuenta que si el archivo / directorio no existe, es un error; documentos para fs.stat
recomendar usar fs.access
si necesita verificar la existencia sin abrir)fs.exists()
todavía está en desuso, pero fs.existsSync()
ya no está en desuso. Para que pueda usarlo con seguridad ahora.Puedes usar statSync
o lstatSync
( docs link ), que te da un fs.Stats
objeto . En general, si una versión síncrona de una función está disponible, tendrá el mismo nombre que la versión asíncrona con Sync
al final. Así statSync
es la versión sincrónica de stat
; lstatSync
es la versión sincrónica de lstat
, etc.
lstatSync
le informa a ambos si algo existe y, de ser así, si se trata de un archivo o un directorio (o en algunos sistemas de archivos, un enlace simbólico, un dispositivo de bloque, un dispositivo de caracteres, etc.), por ejemplo, si necesita saber si existe y si existe un directorio:
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) {
// ...
}
... y de manera similar, si es un archivo, hay isFile
; si es un dispositivo de bloque, hay isBlockDevice
, etc., etc. Tenga en cuenta que try/catch
; arroja un error si la entrada no existe en absoluto.
Si no le importa lo que la entrada es y sólo quiere saber si es que existe, puede utilizar path.existsSync
(o con la última, fs.existsSync
) como se ha señalado por user618408 :
var path = require('path');
if (path.existsSync("/the/path")) { // or fs.existsSync
// ...
}
No requiere un try/catch
pero no le da información sobre qué es la cosa, solo que está allí. path.existsSync
fue en desuso hace mucho tiempo.
Nota al margen: Usted ha preguntado expresamente cómo verificar sincrónicamente , por lo que he usado las xyzSync
versiones de las funciones anteriores. Pero siempre que sea posible, con E / S, lo mejor es evitar las llamadas sincrónicas. Las llamadas al subsistema de E / S toman un tiempo considerable desde el punto de vista de una CPU. Tenga en cuenta lo fácil que es llamar en lstat
lugar de lstatSync
:
// Is it a directory?
lstat('/the/path', function(err, stats) {
if (!err && stats.isDirectory()) {
// Yes it is
}
});
Pero si necesita la versión sincrónica, está ahí.
La siguiente respuesta de hace un par de años ahora está un poco desactualizada. La forma actual es usar fs.existsSync
para hacer una verificación sincrónica de la existencia de un archivo / directorio (o, por supuesto, fs.exists
para una verificación asincrónica), en lugar de las path
versiones a continuación.
Ejemplo:
var fs = require('fs');
if (fs.existsSync(path)) {
// Do something
}
// Or
fs.exists(path, function(exists) {
if (exists) {
// Do something
}
});
Y aquí estamos en 2015 y los documentos del Nodo ahora dicen que fs.existsSync
(y fs.exists
) "quedarán en desuso". (Debido a que la gente del Nodo piensa que es tonto verificar si algo existe antes de abrirlo, lo cual es; ¡pero esa no es la única razón para verificar si algo existe!)
Así que probablemente volvamos a los diversos stat
métodos ... Hasta / a menos que esto cambie una vez más, por supuesto.
No sé cuánto tiempo lleva allí, pero también hay fs.access(path, fs.F_OK, ...)
/fs.accessSync(path, fs.F_OK)
. Y al menos a partir de octubre de 2016, la fs.stat
documentación recomienda usar fs.access
para hacer verificaciones de existencia ( " fs.access()
Se recomienda verificar si un archivo existe sin manipularlo después " ). Pero tenga en cuenta que el acceso que no está disponible se considera un error , por lo que probablemente sea mejor si espera que el archivo sea accesible:
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
}
});
Puedes usar fs.existsSync()
:
if (fs.existsSync(path)) {
// Do something
}
Fue en desuso durante varios años, pero ya no lo es. De los documentos:
Tenga en cuenta que
fs.exists()
está en desuso, perofs.existsSync()
no lo está. (El parámetro de devolución de llamada parafs.exists()
aceptar parámetros que son inconsistentes con otras devoluciones de llamada de Node.js.fs.existsSync()
No utiliza una devolución de llamada).
open
llamada y manejar la excepción o lo que sea si el archivo no fue encontró. Después de todo, el mundo real es caótico: si comprueba primero y está allí, eso no significa que seguirá estando allí cuando intente abrirlo; si verifica primero y no está allí, eso no significa que no estará allí un momento después. Momentos así parecen ser casos extremos, pero surgen todo el tiempo . Entonces, si va a abrir, no tiene sentido verificar primero.
Mirando la fuente, hay una versión sincrónica de path.exists
- path.existsSync
. Parece que se perdió en los documentos.
path.exists
y path.existsSync
ahora están en desuso . Por favor use .fs.exists
yfs.existsSync
fs.exists
y quedado en desuso . Utilice fs.stat () o fs.access () en su lugar.fs.existsSync
también han
uso fs.existsSync
. No está en desuso.
https://nodejs.org/api/fs.html#fs_fs_existssync_path
fs.existsSync
.
exists
función:is-there
fs.exists
como obsoletos mientras fs.existsSync
que no lo están!
Utilizando las API actualmente recomendadas (a partir de 2015) (según los documentos del nodo), esto es lo que hago:
var fs = require('fs');
function fileExists(filePath)
{
try
{
return fs.statSync(filePath).isFile();
}
catch (err)
{
return false;
}
}
En respuesta a la cuestión EPERM planteada por @broadband en los comentarios, eso plantea un buen punto. fileExists () probablemente no sea una buena manera de pensar en esto en muchos casos, porque fileExists () realmente no puede prometer un retorno booleano. Es posible que pueda determinar definitivamente que el archivo existe o no, pero también puede obtener un error de permisos. El error de permisos no implica necesariamente que el archivo exista, porque es posible que no tenga permiso para el directorio que contiene el archivo en el que está comprobando. Y, por supuesto, existe la posibilidad de que encuentre algún otro error al verificar la existencia del archivo.
Entonces, mi código anterior es realmente doesFileExistAndDoIHaveAccessToIt (), pero su pregunta podría ser doesFileNotExistAndCouldICreateIt (), que sería una lógica completamente diferente (que necesitaría tener en cuenta un error EPERM, entre otras cosas).
Si bien la respuesta fs.existsSync aborda la pregunta que se hace aquí directamente, eso a menudo no va a ser lo que desea (no solo quiere saber si "algo" existe en un camino, probablemente le importe si la "cosa" que existe es un archivo o un directorio).
La conclusión es que si está verificando si existe un archivo, probablemente lo esté haciendo porque tiene la intención de tomar alguna acción basada en el resultado, y esa lógica (la verificación y / o la acción posterior) debe acomodar la idea que algo encontrado en esa ruta puede ser un archivo o un directorio, y que puede encontrar EPERM u otros errores en el proceso de verificación.
file.exists()
utilidad simple para el 3% y, en su lugar, ¿nos obligará a envolver esto en un intento de captura? Se real ... Perra del día.
Otra actualización
Al necesitar una respuesta para esta pregunta, busqué los documentos del nodo, parece que no debería usar fs.exists, en su lugar use fs.open y use el error de salida para detectar si un archivo no existe:
de los documentos:
fs.exists () es un anacronismo y existe solo por razones históricas. Casi nunca debería haber una razón para usarlo en su propio código.
En particular, verificar si existe un archivo antes de abrirlo es un antipatrón que lo deja vulnerable a las condiciones de carrera: otro proceso puede eliminar el archivo entre las llamadas a fs.exists () y fs.open (). Simplemente abra el archivo y maneje el error cuando no esté allí.
Yo uso la siguiente función para probar si existe el archivo. Captura también otras excepciones. Entonces, en caso de que haya problemas de derechos, por ejemplo, chmod ugo-rwx filename
o en la Right Click -> Properties -> Security -> Advanced -> Permission entries: empty list ..
función de Windows
, se devuelve la excepción como debería. El archivo existe pero no tenemos derechos para acceder a él. Sería un error ignorar este tipo de excepciones.
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, ...
}
}
Salida de excepción, documentación de errores de nodejs en caso de que el archivo no exista:
{
[Error: ENOENT: no such file or directory, stat 'X:\\delsdfsdf.txt']
errno: -4058,
code: 'ENOENT',
syscall: 'stat',
path: 'X:\\delsdfsdf.txt'
}
Excepción en caso de que no tengamos derechos sobre el archivo, pero exista:
{
[Error: EPERM: operation not permitted, stat 'X:\file.txt']
errno: -4048,
code: 'EPERM',
syscall: 'stat',
path: 'X:\\file.txt'
}
fs.exists () está en desuso No lo use https://nodejs.org/api/fs.html#fs_fs_exists_path_callback
Puede implementar el modo core nodejs utilizado en esto: https://github.com/nodejs/node-v0.x-archive/blob/master/lib/module.js#L86
function statPath(path) {
try {
return fs.statSync(path);
} catch (ex) {}
return false;
}
esto devolverá el objeto de estadísticas y, una vez que tenga el objeto de estadísticas, puede intentar
var exist = statPath('/path/to/your/file.js');
if(exist && exist.isFile()) {
// do something
}
Algunas respuestas aquí dicen eso fs.exists
y fs.existsSync
ambos están en desuso. Según los documentos, esto ya no es cierto. Solo fs.exists
está en desuso ahora:
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 otras devoluciones de llamada de Node.js. Fs.existsSync () no utiliza una devolución de llamada).
Por lo tanto, puede usar fs.existsSync () de forma segura para verificar sincrónicamente si existe un archivo.
El path
módulo no proporciona una versión síncrona, por path.exists
lo que debe engañar con el fs
módulo.
Lo más rápido que puedo imaginar es usarlo, fs.realpathSync
lo que arrojará un error que debe detectar, por lo que debe hacer que su propia función de contenedor con un try / catch.
El uso de las pruebas de fileSystem (fs) activará objetos de error, que luego deberá incluir en una declaración try / catch. Ahórrese un poco de esfuerzo y use una función introducida en la rama 0.4.x.
var path = require('path');
var dirs = ['one', 'two', 'three'];
dirs.map(function(dir) {
path.exists(dir, function(exists) {
var message = (exists) ? dir + ': is a directory' : dir + ': is not a directory';
console.log(message);
});
});
Los documentos sobre fs.stat()
dice usar fs.access()
si no vas a manipular el archivo. No dio una justificación, ¿podría ser un uso más rápido o menos memorable?
Yo uso el nodo para la automatización lineal, así que pensé en compartir la función que uso para probar la existencia del archivo.
var fs = require("fs");
function exists(path){
//Remember file access time will slow your program.
try{
fs.accessSync(path);
} catch (err){
return false;
}
return true;
}
Respuestas actualizadas para aquellas personas que "correctamente" señalan que no responde directamente a la pregunta, más aportan una opción alternativa.
fs.existsSync('filePath')
También vea los documentos aquí .
Devuelve verdadero si la ruta existe, falso de lo contrario.
En un contexto asíncrono, podría escribir la versión asíncrona en el método de sincronización con el uso de la await
palabra clave. Simplemente puede convertir el método de devolución de llamada asíncrono en una promesa como esta:
function fileExists(path){
return new Promise((resolve, fail) => fs.access(path, fs.constants.F_OK,
(err, result) => err ? fail(err) : resolve(result))
//F_OK checks if file is visible, is default does no need to be specified.
}
async function doSomething() {
var exists = await fileExists('filePath');
if(exists){
console.log('file exists');
}
}
los documentos sobre acceso ().
function asyncFileExists(path) { //F_OK checks if file is visible, is default does no need to be specified. return new Promise(function (res, rej) { fs.access( path, fs.constants.F_OK, function (err) { err ? rej(err) : res(true); }, ); }); }
Lo más probable es que, si desea saber si existe un archivo, planea solicitarlo si es así.
function getFile(path){
try{
return require(path);
}catch(e){
return false;
}
}
Aquí hay una solución de envoltura simple para esto:
var fs = require('fs')
function getFileRealPath(s){
try {return fs.realpathSync(s);} catch(e){return false;}
}
Uso:
Ejemplo:
var realPath,pathToCheck='<your_dir_or_file>'
if( (realPath=getFileRealPath(pathToCheck)) === false){
console.log('file/dir not found: '+pathToCheck);
} else {
console.log('file/dir exists: '+realPath);
}
Asegúrese de usar el operador === para probar si return es igual a falso. No hay una razón lógica para que fs.realpathSync () devuelva falso en condiciones de trabajo adecuadas, por lo que creo que esto debería funcionar al 100%.
Preferiría ver una solución que no genere un Error y el impacto en el rendimiento resultante. Desde una perspectiva API, fs.exists () parece la solución más elegante.
De las respuestas parece que no hay soporte oficial de API para esto (como en una verificación directa y explícita). Muchas de las respuestas dicen que use stat, sin embargo, no son estrictas. No podemos suponer, por ejemplo, que cualquier error arrojado por stat significa que algo no existe.
Digamos que lo intentamos con algo que no existe:
$ node -e 'require("fs").stat("god",err=>console.log(err))'
{ Error: ENOENT: no such file or directory, stat 'god' errno: -2, code: 'ENOENT', syscall: 'stat', path: 'god' }
Probémoslo con algo que existe pero al que no tenemos acceso:
$ mkdir -p fsm/appendage && sudo chmod 0 fsm
$ node -e 'require("fs").stat("fsm/appendage",err=>console.log(err))'
{ Error: EACCES: permission denied, stat 'access/access' errno: -13, code: 'EACCES', syscall: 'stat', path: 'fsm/appendage' }
Por lo menos querrás:
let dir_exists = async path => {
let stat;
try {
stat = await (new Promise(
(resolve, reject) => require('fs').stat(path,
(err, result) => err ? reject(err) : resolve(result))
));
}
catch(e) {
if(e.code === 'ENOENT') return false;
throw e;
}
if(!stat.isDirectory())
throw new Error('Not a directory.');
return true;
};
La pregunta no está clara sobre si realmente desea que sea sincrónico o si solo desea que se escriba como si fuera sincrónico. Este ejemplo usa wait / async para que solo se escriba sincrónicamente pero se ejecute de forma asíncrona.
Esto significa que debe llamarlo como tal en el nivel superior:
(async () => {
try {
console.log(await dir_exists('god'));
console.log(await dir_exists('fsm/appendage'));
}
catch(e) {
console.log(e);
}
})();
Una alternativa es usar .then y .catch en la promesa devuelta por la llamada asincrónica si la necesita más abajo.
Si desea verificar si algo existe, es una buena práctica asegurarse también de que es el tipo correcto de cosas, como un directorio o archivo. Esto está incluido en el ejemplo. Si no se permite que sea un enlace simbólico, debe usar lstat en lugar de stat, ya que stat atravesará automáticamente los enlaces.
Puede reemplazar todo el asíncrono para sincronizar el código aquí y usar statSync en su lugar. Sin embargo, espere que una vez que async y espere se vuelvan universalmente compatibles, las llamadas de Sync se volverán redundantes y eventualmente se depreciarán (de lo contrario, tendría que definirlas en todas partes y en la cadena al igual que con async, lo que lo hace realmente inútil).