¿Cuál es la mejor manera de comprobar si un archivo existe en C++? (multiplataforma)


He leído las respuestas para ¿Cuál es la mejor manera de comprobar si existe un archivo en C? (multiplataforma), pero me pregunto si hay una mejor manera de hacer esto usando libs estándar de c++? Preferiblemente sin intentar abrir el archivo en absoluto.

Tanto stat como access son prácticamente imposibles de entender. ¿Qué debo #include para usar estos?

Author: Community, 2008-11-06

9 answers

Use boost:: sistema de archivos :

#include <boost/filesystem.hpp>

if ( !boost::filesystem::exists( "myfile.txt" ) )
{
  std::cout << "Can't find my file!" << std::endl;
}
 150
Author: Andreas Magnusson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-05-28 07:05:52

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

Es mejor ir y abrir el archivo, comprobar si hay algún error y si todo está bien entonces hacer algo con el archivo. Es aún más importante con código crítico para la seguridad.

Detalles sobre seguridad y condiciones de carrera: http://www.ibm.com/developerworks/library/l-sprace.html

 39
Author: rlerallut,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-11-06 12:58:08

Soy un usuario feliz de boost y ciertamente usaría la solución de Andreas. Pero si no tenías acceso a las libs de boost puedes usar la librería stream:

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

No es tan agradable como boost::filesystem::exists ya que el archivo realmente se abrirá...pero eso suele ser lo siguiente que quieres hacer de todos modos.

 27
Author: MattyT,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-11-06 12:36:07

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

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

 10
Author: activout.se,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-11-06 09:16:18

¿Qué tal access?

#include <io.h>

if (_access(filename, 0) == -1)
{
    // File does not exist
}
 9
Author: Rob,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-11-06 10:10:13

Otra posibilidad consiste en usar la función good() en la secuencia:

#include <fstream>     
bool checkExistence(const char* filename)
{
     ifstream Infield(filename);
     return Infield.good();
}
 8
Author: Samer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-29 13:27:57

Reconsideraría intentar averiguar si existe un archivo. En su lugar, debe intentar abrirlo (en C estándar o C++) en el mismo modo que pretende usarlo. ¿De qué sirve saber que el archivo existe si, por ejemplo, no se puede escribir cuando se necesita usarlo?

 7
Author: fizzer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-11-06 12:05:48

NO boost REQUIRED, que sería un overkill.


Use stat () (aunque no multiplataforma como lo menciona 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 aquí.

 2
Author: gsamaras,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-21 18:35:25

Si ya está utilizando la clase de flujo de archivos de entrada (ifstream), podría usar su función fail().

Ejemplo:

ifstream myFile;

myFile.open("file.txt");

// Check for errors
if (myFile.fail()) {
    cerr << "Error: File could not be found";
    exit(1);
}
 0
Author: Reza Saadati,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-27 00:54:48