std :: ofstream, проверьте, существует ли файл перед записью - PullRequest
33 голосов
/ 30 ноября 2010

Я реализую функцию сохранения файлов в приложении Qt с использованием C ++.

Я ищу способ проверить, существует ли уже выбранный файл перед записью в него, чтобы я мог предложить пользователю предупреждение.

Я использую std::ofstream и не ищу решения Boost .

Ответы [ 6 ]

63 голосов
/ 09 июня 2011

Это одна из моих любимых функций подкладки, которую я держу под рукой для многократного использования.

#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;
}

Я считаю, что это гораздо вкуснее, чем пытаться открыть файл, если у вас нет непосредственных намерений использовать его для ввода-вывода.

38 голосов
/ 15 июня 2012
bool fileExists(const char *fileName)
{
    ifstream infile(fileName);
    return infile.good();
}

Этот метод пока самый короткий и самый портативный. Если использование не очень изощренное, я бы выбрал именно это. Если вы также хотите вызвать предупреждение, я бы сделал это в основном.

9 голосов
/ 09 июня 2011
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

Обратите внимание, что в случае существующего файла он откроется в режиме произвольного доступа. При желании вы можете закрыть его и снова открыть в режиме добавления или усечения.

4 голосов
/ 30 ноября 2010

Попробуйте ::stat() (заявлено в <sys/stat.h>)

2 голосов
/ 30 июля 2016

Одним из способов было бы сделать stat() и проверить errno.
Пример кода будет выглядеть так:

#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
}

Это работает независимо от потока. Если вы все еще предпочитаете проверять, используя ofstream, просто проверьте, используя is_open().
Пример:

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

Надеюсь, это поможет. Спасибо!

1 голос
/ 18 июня 2018

С std::filesystem::exists 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.
        }
    }
}

См. Также std::error_code.

Если вы хотите проверить, является ли путь, по которому вы пишете, обычным файлом, используйте std::filesystem::is_regular_file.

...