Me gustaría encontrar la forma más rápida de verificar si un archivo existe en C ++ 11, C ++ o C. estándar. Tengo miles de archivos y antes de hacer algo en ellos necesito verificar si todos existen. ¿Qué puedo escribir en lugar de /* SOMETHING */
en la siguiente función?
inline bool exist(const std::string& name)
{
/* SOMETHING */
}
boost::filesystem
Parece que usastat()
. (Suponiendo de la documentación.) No creo que pueda hacer mucho más rápido para las llamadas FS. La forma de hacer lo que está haciendo rápido es "evitar mirar miles de archivos".git push
probablemente no se moleste en asegurarse de que no esté tocando el árbol de trabajo después de la verificación sucia inicial.Respuestas:
Bueno, elaboré un programa de prueba que ejecutaba cada uno de estos métodos 100,000 veces, la mitad en archivos que existían y la otra mitad en archivos que no existían.
Los resultados del tiempo total para ejecutar las 100,000 llamadas promediaron más de 5 ejecuciones,
La
stat()
función proporcionó el mejor rendimiento en mi sistema (Linux, compilado cong++
), siendo unafopen
llamada estándar su mejor opción si por alguna razón se niega a usar las funciones POSIX.fuente
stat()
Parece comprobar la existencia.f.close()
ya que f sale del alcance al final de la función. Entoncesreturn f.good()
, ¿ podría reemplazar elif
bloque?Observación: en C ++ 14 y tan pronto como el sistema de archivos TS esté terminado y adoptado, la solución será usar:
y desde C ++ 17, solo:
fuente
std::tr2::sys::exists("helloworld.txt");
std::exists
, eso sería bastante confuso (piense: existe en un contenedor STL como un conjunto).#include <experimental/filesystem> bool file_exists(std::string fn) { std::experimental::filesystem::exists("helloworld.txt"); }
#include <experimental/filesystem>
Utilizo este código, hasta ahora funciona bien conmigo. Esto no utiliza muchas características sofisticadas de C ++:
fuente
ifstream
se llamará al destructor al saliris_file_exist
y cerrará la transmisión.return std::ifstream(fileName);
Depende de dónde residan los archivos. Por ejemplo, si se supone que todos están en el mismo directorio, puede leer todas las entradas del directorio en una tabla hash y luego verificar todos los nombres en la tabla hash. Esto puede ser más rápido en algunos sistemas que verificar cada archivo individualmente. La forma más rápida de verificar cada archivo individualmente depende de su sistema ... si está escribiendo ANSI C, la forma más rápida es
fopen
porque es la única forma (un archivo puede existir pero no puede abrirse, pero probablemente realmente quiera abrirlo si necesita "hacer algo al respecto"). C ++, POSIX, Windows ofrecen opciones adicionales.Mientras estoy en ello, permítanme señalar algunos problemas con su pregunta. Dices que quieres la forma más rápida y que tienes miles de archivos, pero luego pides el código de una función para probar un solo archivo (y esa función solo es válida en C ++, no en C). Esto contradice sus requisitos al asumir que la solución ... es un caso del problema XY . También dice "en c ++ 11 estándar (o) c ++ (o) c" ... que son todos diferentes, y esto también es inconsistente con su requisito de velocidad ... la solución más rápida implicaría adaptar el código a objetivo del sistema. La inconsistencia en la pregunta se destaca por el hecho de que aceptó una respuesta que brinda soluciones que dependen del sistema y no son C o C ++ estándar.
fuente
Para aquellos que les gusta el impulso:
fuente
Sin usar otras bibliotecas, me gusta usar el siguiente fragmento de código:
Esto funciona multiplataforma para Windows y sistemas compatibles con POSIX.
fuente
unistd.h
. ¿Quizás el primero#ifdef
debería ser específico de Windows?Igual a lo sugerido por PherricOxide pero en C
fuente
fuente
close()
que no es necesario.Otras 3 opciones en Windows:
1
2
3
fuente
GetFileAttributes
versión es básicamente la forma canónica de hacerlo en Windows.También puedes hacer
bool b = std::ifstream('filename').good();
. Sin las instrucciones de bifurcación (como si) debe funcionar más rápido, ya que debe llamarse miles de veces.fuente
Si necesita distinguir entre un archivo y un directorio, considere lo siguiente, que usan stat, que es la herramienta estándar más rápida como lo demuestra PherricOxide:
fuente
Necesito una función rápida que pueda verificar si un archivo existe o no, y la respuesta de PherricOxide es casi lo que necesito, excepto que no compara el rendimiento de boost :: filesystem :: Existe y abre funciones. De los resultados de referencia podemos ver fácilmente que:
Usar la función estadística es la forma más rápida de verificar si existe un archivo. Tenga en cuenta que mis resultados son consistentes con los de la respuesta de PherricOxide.
El rendimiento de la función boost :: filesystem :: exist es muy similar al de la función stat y también es portátil. Recomendaría esta solución si se puede acceder a las bibliotecas de impulso desde su código.
Resultados de referencia obtenidos con el kernel 4.17.0 de Linux y gcc-7.3:
A continuación se muestra mi código de referencia:
fuente
Puede usar
std::ifstream
, comois_open
,fail
por ejemplo, como se muestra a continuación (el código "abierto" significa que el archivo existe o no):citado de esta respuesta
fuente
¿Dónde
R
está su secuencia de cosas similares a la ruta, yexists()
es del futuro estándar o impulso actual? Si rueda el suyo, que sea sencillo,La solución ramificada no es absolutamente terrible y no engullirá los descriptores de archivo,
fuente
PathFileExists
está limitado aMAX_PATH
(260) caracteres;GetFileAttributes
No tiene esta limitación.GetFileAttributes
también está limitado a MAX_PATH. Los documentos describen una solución alternativa si utiliza rutas absolutas, unicode y antepone una cadena de prefijo especial al nombre de la ruta. Creo que estamos en una tangente con las respuestas específicas de Windows de todos modos.GetFileAttributesW
No tiene la limitación.En C ++ 17:
fuente
Usando MFC es posible con lo siguiente
¿Dónde
FileName
está una cadena que representa el archivo que está buscando para la existencia?fuente
solo hay una forma más rápida de verificar si el archivo existe y si tiene permiso para leerlo, la forma en que usa el lenguaje C es más rápido y se puede usar en cualquier versión en C ++
solución : en C hay una biblioteca errno.h que tiene una variable entera externa (global) llamada errno que contiene un número que puede usarse para reconocer el tipo de error
fuente
Aunque hay varias maneras de hacer esto, la solución más eficiente para su problema probablemente sería usar uno de los métodos predefinidos de fstream como good () . Con este método puede verificar si el archivo que ha especificado existe o no.
Espero que encuentres esto útil.
fuente