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
How to check if a file exists before creating a new 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
回答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++?
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;
}
stat
returns 0
if the file exists and -1
if not.
stat
0
如果文件存在-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 open
system 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::exists
and std::filesystem::is_regular_file
.
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.
}
}
回答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
.