web-dev-qa-db-ja.com

std :: ofstream、書き込み前にファイルが存在するかどうかを確認します

C++を使用してQtアプリケーション内にファイル保存機能を実装しています。

ユーザーに警告を表示できるように、選択したファイルが書き込み前に既に存在するかどうかを確認する方法を探しています。

私はstd::ofstreamを使用していますが、ブーストソリューションを探していません。

33
cweston

これは、複数の用途のために手元に置いておくお気に入りの隠れた機能の1つです。

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

I/Oに使用する直接的な意図がない場合、ファイルを開こうとするよりも、これははるかに上品です。

64
Rico
bool fileExists(const char *fileName)
{
    ifstream infile(fileName);
    return infile.good();
}

この方法は、これまでのところ最短で最も移植性の高い方法です。使い方があまり洗練されていない場合、これは私が求めるものです。また、警告を表示する場合は、メインでそれを行います。

38
return 0
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

既存のファイルの場合、これはランダムアクセスモードでそれを開くことに注意してください。必要に応じて、ファイルを閉じて、追加モードまたは切り捨てモードで再度開くことができます。

9
HighCommander4

::stat() を試してください(<sys/stat.h>

4
NPE

方法の1つは、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
_

お役に立てれば。ありがとう!

2

C++ 17の std::filesystem::exists の場合:

#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 を使用します。

1
Roi Danton