2008-11-06 22 views
80

He leído las respuestas para What's the best way to check if a file exists in C? (cross platform), pero me pregunto si hay una forma mejor de hacerlo con las bibliotecas estándar de C++. Preferiblemente sin intentar abrir el archivo en absoluto.¿Cuál es la mejor manera de verificar si un archivo existe en C++? (plataforma cruzada)

Ambos stat y access son bastante ingociables. ¿Qué debería usar #include para usar esto?

+0

para el acceso (que en realidad podría ser _acceso). – Rob

+0

Sí, como se indicó a continuación. – c0m4

Respuesta

139

Uso boost::filesystem:

#include <boost/filesystem.hpp> 

if (!boost::filesystem::exists("myfile.txt")) 
{ 
    std::cout << "Can't find my file!" << std::endl; 
} 
+60

Parece ser un poco extraño para instalar una enorme biblioteca de terceros para hacer algo que * debería * ser simple – c0m4

+78

Boost es una biblioteca donde se desarrolla gran parte de lo que eventualmente formará parte de la biblioteca estándar de C++. Muchas de las personas involucradas con el impulso son personas involucradas con el estándar de C++. Así que aumentar no es solo * cualquier * biblioteca de terceros. ¡Si estás programando en C++ * debes * tener un impulso instalado! –

+0

Me parece recordar que b :: fs :: exists devuelve "verdadero" en archivos no existentes en recursos compartidos de red: "\\ machine \ share \ this_file_doesnt_exist" => true. La última vez que revisé estaba en boost 1.33, tenga cuidado ... – rlerallut

9

Use stat(), si es lo suficientemente multiplataforma para sus necesidades. Sin embargo, no es estándar en C++, sino POSIX.

En MS Windows hay _stat, _stat64, _stati64, _wstat, _wstat64, _wstati64.

+0

Ok, ¿qué debo #incluir? – c0m4

+1

y Ver http://msdn.microsoft.com/en-us/library/14h5k7ff(VS.71).aspx –

+0

Niza 1 respuesta para ** NO USAR BOOST **, ya que es una exageración, sin embargo, no fue trivial escribir eso a partir de lo que aquí se proporciona, así que acabo de publicar una respuesta. Verifícalo por favor. – gsamaras

7

¿Qué tal access?

#include <io.h> 

if (_access(filename, 0) == -1) 
{ 
    // File does not exist 
} 
+0

Is io. h normalmente disponible en Windows y Linux, incluso si no es estándar? – c0m4

+1

access() es la función POSIX que está disponible a través de en Linux. –

6

Me gustaría reconsiderar el intento de averiguar si existe un archivo. En su lugar, debe tratar de abrirlo (en Estándar C o C++) en el mismo modo que tiene la intención de usarlo. ¿De qué sirve saber que el archivo existe si, por ejemplo, no puede escribirse cuando lo necesita?

+0

¿Qué sucede si estás escribiendo un programa 'ls'? Supongo que el póster original aquí no quiere abrir el archivo, en absoluto. La función de estadísticas de Posix se supone que le dará información sobre los permisos del archivo, por lo que solucionaría ese problema. – Michael

26

Soy un feliz usuario de impulso y sin duda usaría la solución de Andreas. Pero si usted no tiene acceso a las bibliotecas de impulso puede utilizar la biblioteca de corriente:

ifstream file(argv[1]); 
if (!file) 
{ 
    // Can't open file 
} 

No es tan agradable como impulso :: :: sistema de archivos ya existe en realidad se puede abrir el archivo ... pero entonces, por lo general, eso es lo próximo que quieres hacer de todos modos.

+14

Pero con este código también accederá a la cláusula if si no tiene permisos para el archivo, aunque existe. En la mayoría de los casos no importará, pero aún vale la pena mencionarlo. –

+1

Advirtió que good() también produce verdadero si el argumento dado denota un directorio, vea http://stackoverflow.com/questions/9591036/ifstream-open-doesnt-set-error-bits-when-argument-is-a- directorio – FelixJongleur42

35

Tenga cuidado con las condiciones de carrera: si el archivo desaparece entre la marca "exists" y la hora en que lo abre, su programa fallará inesperadamente.

Es mejor ir y abrir el archivo, verificar el error y si todo está bien, entonces haga algo con el archivo. Es aún más importante con el código de seguridad crítica.

Los detalles sobre las condiciones de seguridad y de raza: http://www.ibm.com/developerworks/library/l-sprace.html

7

Otra posibilidad consiste en utilizar la función good() en la corriente:

#include <fstream>  
bool checkExistence(const char* filename) 
{ 
    ifstream Infield(filename); 
    return Infield.good(); 
} 
+0

¿Por qué no 'return Infield.good()'? –

+0

@ RadosławM Por supuesto que puedes hacer eso. Lo hice de esta manera solo por motivos de ilustración. – Samer

2

NO requiere, lo que sería un exageración.


Uso stat() (plataforma no cruzada, aunque como se ha mencionado por pavon), así:

#include <sys/stat.h> 
#include <iostream> 

// true if file exists 
bool fileExists(const std::string& file) { 
    struct stat buf; 
    return (stat(file.c_str(), &buf) == 0); 
} 

int main() { 
    if(!fileExists("test.txt")) { 
     std::cerr << "test.txt doesn't exist, exiting...\n"; 
     return -1; 
    } 
    return 0; 
} 

Salida:

C02QT2UBFVH6-lm:~ gsamaras$ ls test.txt 
ls: test.txt: No such file or directory 
C02QT2UBFVH6-lm:~ gsamaras$ g++ -Wall main.cpp 
C02QT2UBFVH6-lm:~ gsamaras$ ./a.out 
test.txt doesn't exist, exiting... 

Otra versión (y que) se puede encontrar here.

+0

Sr./Sra. Infractor, si cree que esta respuesta se puede mejorar, indique cómo hacerlo. :) – gsamaras

+0

No es el infractor, pero la pregunta que se hace es una solución multiplataforma, y ​​la estadística no existe en todas las plataformas. – pavon

+0

¡Oh, eso es correcto @pavon, gracias! – gsamaras

Cuestiones relacionadas