¿Cómo puedo comprobar de forma sincrónica, utilizando node.JS ¿existe un archivo o directorio?
Respuestas
¿Demasiados anuncios?Actualización
La respuesta que aparece a continuación, de hace un par de años, está ya un poco desfasada. La forma actual es utilizar fs.existsSync
para hacer una comprobación sincrónica de la existencia de archivos/directorios (o por supuesto fs.exists
para una comprobación asíncrona), en lugar del path
versiones inferiores.
Ejemplo:
var fs = require('fs');
if (fs.existsSync(path)) {
// Do something
}
// Or
fs.exists(path, function(exists) {
if (exists) {
// Do something
}
});
Respuesta original de 2010:
Puede utilizar statSync
o lstatSync
( enlace a los documentos ), que le dan un fs.Stats
objeto . En general, si existe una versión sincrónica de una función, ésta tendrá el mismo nombre que la versión asincrónica con Sync
al final. Así que statSync
es la versión sincrónica de stat
; lstatSync
es la versión sincrónica de lstat
etc.
lstatSync
te dice tanto si algo existe, como si es un archivo o un directorio (o en algunos sistemas de archivos, un enlace simbólico, un dispositivo de bloques, un dispositivo de caracteres, etc.), por ejemplo, si necesitas saber si existe y es 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 se trata de un dispositivo en bloque, hay isBlockDevice
etc., etc. Tenga en cuenta la try/catch
; arroja un error si la entrada no existe en absoluto.
Si no te importa lo que la entrada es y sólo quiere saber si existe, puede utilizar path.existsSync
(o con lo último, fs.existsSync
) como anotado por el usuario618408 :
var path = require('path');
if (path.existsSync("/the/path")) { // or fs.existsSync
// ...
}
No requiere una try/catch
pero no te da ninguna información sobre qué es la cosa, sólo que está ahí.
Nota al margen: Usted ha preguntado expresamente cómo comprobar Sincrónicamente Así que he utilizado el xyzSync
de las funciones anteriores. Pero siempre que sea posible, con la E/S, realmente es mejor evitar las llamadas sincrónicas. Las llamadas al subsistema de E/S toman un tiempo significativo desde el punto de vista de la CPU. Observe lo fácil que es llamar a lstat
en lugar de lstatSync
:
// Is it a directory?
lstat('/the/path', function(err, stats) {
if (!err && stats.isDirectory()) {
// Yes it is
}
});
Pero si necesitas la versión sincrónica, está ahí.
Usando las APIs actualmente recomendadas (a partir de 2015) (según los documentos de Node), 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 de EPERM planteada por @broadband en los comentarios, que trae un buen punto. fileExists() no es probablemente una buena manera de pensar en esto en muchos casos, porque fileExists() no puede realmente prometer un retorno booleano. Usted puede ser capaz de determinar definitivamente que el archivo existe o no existe, pero también puede obtener un error de permisos. El error de permisos no implica necesariamente que el archivo exista, porque podrías carecer de permisos en el directorio que contiene el archivo que estás comprobando. Y, por supuesto, existe la posibilidad de que te encuentres con algún otro error al comprobar la existencia del archivo.
Así que mi código de arriba es realmente doesFileExistAndDoIHaveAccessToIt(), pero tu 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).
Aunque la respuesta de fs.existsSync aborda directamente la pregunta formulada aquí, a menudo no será lo que usted desea (no sólo quiere saber si "algo" existe en una ruta, probablemente le interesa saber si la "cosa" que existe es un archivo o un directorio).
La conclusión es que si está comprobando si un archivo existe, probablemente lo está haciendo porque tiene la intención de tomar alguna acción basada en el resultado, y esa lógica (la comprobación y/o la acción subsiguiente) debe acomodar la idea de que una cosa encontrada en esa ruta puede ser un archivo o un directorio, y que puede encontrar EPERM u otros errores en el proceso de comprobación.
Otra actualización
Necesitando una respuesta a esta pregunta yo mismo busqué los documentos del nodo, parece que debe no estar utilizando fs.exists, en su lugar utilizar fs.open y utilizar el error de salida para detectar si un archivo no existe:
de los documentos:
fs.exists() es un anacronismo y existe sólo por razones históricas. Casi nunca debería haber una razón para usarlo en su propio código.
En particular, comprobar si un archivo existe antes de abrirlo es un es un anti-patrón que te deja vulnerable a 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é no está.
Utilizo la siguiente función para comprobar si el archivo existe. También atrapa otras excepciones. Así que en caso de que haya problemas de derechos, por ejemplo chmod ugo-rwx filename
o en Windows Right Click -> Properties -> Security -> Advanced -> Permission entries: empty list ..
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 sobre 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 existe:
{
[Error: EPERM: operation not permitted, stat 'X:\file.txt']
errno: -4048,
code: 'EPERM',
syscall: 'stat',
path: 'X:\\file.txt'
}
- Ver respuestas anteriores
- Ver más respuestas