std:: ofstream, comprueba si el archivo existe antes de escribir


Estoy implementando la funcionalidad de guardado de archivos dentro de una aplicación Qt usando C++.

Estoy buscando una manera de comprobar si el archivo seleccionado ya existe antes de escribir en él, para que pueda solicitar una advertencia al usuario.

Estoy usando un std::ofstream y no estoy buscando una solución Boost.

Author: Willi Mentzel, 2010-11-30

6 answers

Esta es una de mis funciones tuck-away favoritas que tengo a mano para múltiples usos.

#include <sys/stat.h>
// Function: fileExists
/**
    Check if a file exists
@param[in] filename - the name of the file to check

@return    true if the file exists, else false

*/
bool fileExists(const std::string& filename)
{
    struct stat buf;
    if (stat(filename.c_str(), &buf) != -1)
    {
        return true;
    }
    return false;
}

Encuentro esto mucho más de buen gusto que intentar abrir un archivo si no tiene intenciones inmediatas de usarlo para E/S.

 60
Author: Rico,
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
2011-06-10 14:33:36
bool fileExists(const char *fileName)
{
    ifstream infile(fileName);
    return infile.good();
}

Este método es hasta ahora el más corto y portátil. Si el uso no es muy sofisticado, este es uno que me gustaría. Si también quieres avisar, lo haría en general.

 39
Author: return 0,
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-06-15 18:41:12
fstream file;
file.open("my_file.txt", ios_base::out | ios_base::in);  // will not create file
if (file.is_open())
{
    cout << "Warning, file already exists, proceed?";
    if (no)
    { 
        file.close();
        // throw something
    }
}
else
{
    file.clear();
    file.open("my_file.txt", ios_base::out);  // will create if necessary
}

// do stuff with file

Tenga en cuenta que en el caso de un archivo existente, esto lo abrirá en modo de acceso aleatorio. Si lo prefiere, puede cerrarlo y volver a abrirlo en modo anexar o truncar.

 7
Author: HighCommander4,
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
2011-06-09 18:40:23

Intente ::stat() (declarado en <sys/stat.h>)

 4
Author: NPE,
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-11-01 23:23:32

Una de las formas sería hacer stat() y comprobar errno.
Un código de ejemplo se vería así:

#include <sys/stat.h>
using namespace std;
// some lines of code...

int fileExist(const string &filePath) {
    struct stat statBuff;
    if (stat(filePath.c_str(), &statBuff) < 0) {
        if (errno == ENOENT) return -ENOENT;
    }
    else
        // do stuff with file
}

Esto funciona independientemente de la secuencia. Si todavía prefiere verificar usando ofstream, simplemente verifique usando is_open().
Ejemplo:

ofstream fp.open("<path-to-file>", ofstream::out);
if (!fp.is_open()) 
    return false;
else 
    // do stuff with file

Espero que esto ayude. ¡Gracias!

 2
Author: Bhagyesh Dudhediya,
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
2016-07-30 10:30:40

Con std::filesystem::exists de C++17:

#include <filesystem> // C++17
#include <iostream>
namespace fs = std::filesystem;

int main()
{
    fs::path filePath("path/to/my/file.ext");
    std::error_code ec; // For using the noexcept overload.
    if (!fs::exists(filePath, ec) && !ec)
    {
        // Save to file, e.g. with std::ofstream file(filePath);
    }
    else
    {
        if (ec)
        {
            std::cerr << ec.message(); // Replace with your error handling.
        }
        else
        {
            std::cout << "File " << filePath << " does already exist.";
            // Handle overwrite case.
        }
    }
}

Véase también std::error_code.

En caso de que desee comprobar si la ruta en la que está escribiendo es realmente un archivo normal, use std::filesystem::is_regular_file.

 0
Author: Roi Danton,
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-06-18 17:19:38