web-dev-qa-db-ja.com

新しいファイルを作成する前にファイルが存在するかどうかを確認する方法

ファイルに内容を入力したいのですが、作成したい名前のファイルが存在するかどうかを最初に確認したいと思います。その場合、ファイルが空であっても、ファイルを作成したくありません。

私の試み

bool CreateFile(char name[], char content[]){
     std::ofstream file(name);
     if(file){
         std::cout << "This account already exists" << std::endl;
        return false;
     }
     file << content;
     file.close();
     return true;
}

私がやりたいことをする方法はありますか?

27
Lion King

操作がアトミックではないとしても、次のことができます。

if (std::ifstream(name))
{
     std::cout << "File already exists" << std::endl;
     return false;
}
std::ofstream file(name);
if (!file)
{
     std::cout << "File could not be created" << std::endl;
     return false;
}
... 

同じファイルを作成しようとする複数のスレッドを実行する場合、これは機能せず、 [〜#〜] toctui [〜 #〜] 問題。 [最初にファイルが存在するかどうかを確認してから作成します。ただし、チェックと作成の間に他の誰かが作成することもできます。それが重要な場合は、移植性のない別の作業が必要です。

さらに問題は、ファイルが読み取り可能ではない(読み取り用に開くことができない)が、書き込み可能であるなどのアクセス許可がある場合、ファイルを上書きすることです。

ほとんどの場合、「ベストエフォート」アプローチで「既にそのようなファイルを持っている」(またはそのようなファイルがある)ことを誰かに伝えるだけなので、これらのことはどちらも重要ではありません。

27
Mats Petersson

boostも使用できます。

 boost::filesystem::exists( filename );

ファイルとフォルダーで機能します。

そして、ファイルシステムがSTLの一部であるC++ 14の準備ができたものに近い実装があります( here を参照)。

13
alexbuisson

試して

ifstream my_file("test.txt");
if (my_file)
{
 // do stuff
}

From: ファイルが存在し、C++で読み取り可能かどうかを確認する方法?

または、ブースト機能を使用できます。

8
CBIII

これを試してください(Erik Garrisonからコピーしたもの: https://stackoverflow.com/a/3071528/5755

#include <sys/stat.h>

bool FileExists(char* filename) 
{
    struct stat fileInfo;
    return stat(filename, &fileInfo) == 0;
}

statは、ファイルが存在する場合は0を返し、存在しない場合は-1を返します。

7
dumbledad

C++ 17の時点では次のとおりです。

if (std::filesystem::exists(pathname)) {
   ...
6
James Hirschorn

少し調べてみたところ、私が見つけたのはopenシステムコールを使用することだけでした。これは、ファイルが既に存在する場合に失敗する方法でファイルを作成できるようにする唯一の機能です

#include <fcntl.h>
#include <errno.h>

int f=open(filename, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
if (f < 0) {
  /* file exists or otherwise uncreatable
     you might want to check errno*/
}else {
  /* File is open to writing */
}

ファイルを作成しているので、許可を与える必要があることに注意してください。

これにより、競合状態が解消されます。

2
rabensky

C++ 17、クロスプラットフォーム: std::filesystem::exists および std::filesystem::is_regular_file

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

bool CreateFile(const fs::path& filePath, const std::string& content)
{
    try
    {
        if (fs::exists(filePath))
        {
            std::cout << filePath << " already exists.";
            return false;
        }
        if (!fs::is_regular_file(filePath))
        {
            std::cout << filePath << " is not a regular file.";
            return false;
        }
    }
    catch (std::exception& e)
    {
        std::cerr << __func__ << ": An error occurred: " << e.what();
        return false;
    }
    std::ofstream file(filePath);
    file << content;
    return true;
}
int main()
{
    if (CreateFile("path/to/the/file.ext", "Content of the file"))
    {
        // Your business logic.
    }
}
0
Roi Danton

私はこのテストを見ました:

bool getFileExists(const TCHAR *file)
{ 
  return (GetFileAttributes(file) != 0xFFFFFFFF);
}
0
Racky