C++ 如何在创建新文件之前检查文件是否存在

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17818099/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 21:28:10  来源:igfitidea点击:

How to check if a file exists before creating a new file

c++file

提问by Lion King

I want to input some contents to a file, but I'd like to check first if a file with the name I wish to create exists. If so, I don't want to create any file, even if the file is empty.

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

My attempt

我的尝试

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

Is there any way to do what I want?

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

采纳答案by Mats Petersson

Assuming it is OK that the operation is not atomic, you can do:

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

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

Note that this doesn't work if you run multiple threads trying to create the same file, and certainly will not prevent a second process from "interfering" with the file creation because you have TOCTUIproblems. [We first check if the file exists, and then create it - but someone else could have created it in between the check and the creation - if that's critical, you will need to do something else, which isn't portable].

请注意,如果您运行多个线程尝试创建同一个文件,这将不起作用,并且肯定不会阻止第二个进程“干扰”文件创建,因为您有TOCTUI问题。[我们首先检查文件是否存在,然后创建它——但其他人可能在检查和创建之间创建了它——如果这很关键,你将需要做一些其他的事情,这不是可移植的]。

A further problem is if you have permissions such as the file is not readable (so we can't open it for read) but is writeable, it will overwrite the file.

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

In MOST cases, neither of these things matter, because all you care about is telling someone that "you already have a file like that" (or something like that) in a "best effort" approach.

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

回答by alexbuisson

you can also use Boost.

你也可以使用升压。

 boost::filesystem::exists( filename );

it works for files and folders.

它适用于文件和文件夹。

And you will have an implementation close to something ready for C++14 in which filesystem should be part of the STL (see here).

并且您将有一个接近于为 C++14 准备的实现,其中文件系统应该是 STL 的一部分(请参阅此处)。

回答by CBIII

Try

尝试

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

From: How to check if a file exists and is readable in C++?

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

or you could use boost functions.

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

回答by dumbledad

Try this (copied-ish from Erik Garrison: https://stackoverflow.com/a/3071528/575530)

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

#include <sys/stat.h>

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

statreturns 0if the file exists and -1if not.

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

回答by James Hirschorn

As of C++17 there is:

从 C++17 开始,有:

if (std::filesystem::exists(pathname)) {
   ...

回答by rabensky

Looked around a bit, and the only thing I find is using the opensystem call. It is the only function I found that allows you to create a file in a way that will fail if it already exists

环顾四周,我唯一发现的是使用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 */
}

Note that you have to give permissions since you are creating a file.

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

This also removes any race conditions there might be

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

回答by Roi Danton

C++17, cross-platform: Using std::filesystem::existsand std::filesystem::is_regular_file.

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

回答by Racky

I just saw this test:

我刚看到这个测试:

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

回答by Vaibhav

The easiest way to do this is using ios :: noreplace.

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