27

我想在文件中输入一些内容,但我想先检查是否存在具有我希望创建的名称的文件。如果是这样,我不想创建任何文件,即使文件是空的。

我的尝试

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

有什么办法可以做我想做的事吗?

4

9 回答 9

30

假设操作不是原子的可以,你可以这样做:

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问题。[我们首先检查文件是否存在,然后创建它 - 但其他人可能在检查和创建之间创建它 - 如果这很关键,您将需要做一些其他不可移植的事情]。

另一个问题是,如果您有权限,例如文件不可读(因此我们无法打开它进行读取)但可写,它将覆盖文件。

在大多数情况下,这些事情都不重要,因为您所关心的只是以“尽力而为”的方式告诉某人“您已经拥有这样的文件”(或类似的东西)。

于 2013-07-23T18:30:47.017 回答
13

你也可以使用升压。

 boost::filesystem::exists( filename );

它适用于文件和文件夹。

您将获得一个接近于 C++14 的实现,其中文件系统应该是 STL 的一部分(参见此处)。

于 2013-07-23T18:35:39.090 回答
8

尝试

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

来自:如何检查文件是否存在并且在 C++ 中是否可读?

或者您可以使用增强功能。

于 2013-07-23T18:30:18.740 回答
7

试试这个(来自 Erik Garrison 的复制:https ://stackoverflow.com/a/3071528/575530 )

#include <sys/stat.h>

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

stat0如果文件存在则返回,否则返回-1

于 2013-10-10T12:53:49.360 回答
7

从 C++17 开始,有:

if (std::filesystem::exists(pathname)) {
   ...
于 2016-12-19T05:34:17.883 回答
2

环顾了一下,我唯一发现的是使用open系统调用。这是我发现的唯一一个功能,它允许您以一种如果文件已经存在就会失败的方式创建文件

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

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

请注意,由于您正在创建文件,因此您必须授予权限。

这也消除了可能存在的任何竞争条件

于 2013-07-23T18:56:08.020 回答
0

我刚看到这个测试:

bool getFileExists(const TCHAR *file)
{ 
  return (GetFileAttributes(file) != 0xFFFFFFFF);
}
于 2016-08-17T12:07:28.330 回答
0

C++17,跨平台:使用std::filesystem::existsstd::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.
    }
}
于 2018-06-18T16:39:03.947 回答
-1

最简单的方法是使用ios :: noreplace.

于 2016-12-16T15:20:27.000 回答