c++ - 如果发现任何重复项,如何创建修改的文件
问题描述
我希望通过用户提供的名称创建一个文件。如果文件名已经存在,我希望在创建之前自动修改文件名。
if (GetFileAttributesA((name).c_str()) != INVALID_FILE_ATTRIBUTES)
{
int num = 0;
//If True: Modify File Name
while (GetFileAttributesA((name + "" + to_string(num) + "").c_str()) != INVALID_FILE_ATTRIBUTES)
{
cout << (GetFileAttributesA((name + "" + to_string(num) + "").c_str()) != INVALID_FILE_ATTRIBUTES) << endl;
num++;
}
CreateFileA((name + "" + to_string(num) + "" + ".txt").c_str(), NULL, NULL, NULL, 2, NULL, NULL);
cout << "Created new file at: ";
cout << (name + "" + to_string(num) + "" + ".txt").c_str() << endl;
}
else
{
CreateFileA(name.c_str(), NULL, NULL, NULL, 2, NULL, NULL);
cout << "Created new file at: ";
cout << (name + ".txt").c_str() << endl;
}
第一次运行程序
Created new file at: Created new file at: D:\Users\Me\HD-Visual Studio Repos\Visual Studio Repo\McFG\Text Generator Function Generator\Generated txt\base.txt
第二次运行程序
Created new file at: Created new file at: D:\Users\Me\HD-Visual Studio Repos\Visual Studio Repo\McFG\Text Generator Function Generator\Generated txt\base1.txt
第三次运行程序
Created new file at: Created new file at: D:\Users\Me\HD-Visual Studio Repos\Visual Studio Repo\McFG\Text Generator Function Generator\Generated txt\base1.txt
到第三次它开始再次创建重复项。
name = D:\Users\Me\HD-Visual Studio Repos\Visual Studio Repo\McFG\Text Generator Function Generator\Generated txt\base
解决方案
使用GetFileAttributes()
您的方式会引入竞争条件。在您检查文件是否存在之后并且在您可以打开/创建它之前,另一个进程可以创建/删除该文件。 CreateFile()
如果文件已存在,则具有使其失败的标志,您应该改用该功能。在您的示例中,将dwCreationDisposition
参数设置为 2 ( CREATE_ALWAYS
) 会覆盖现有文件。请改为将参数设置为 1 ( CREATE_NEW
)。根据文档:
CREATE_ALWAYS
2总是创建一个新文件。
如果指定的文件存在且可写,则该函数覆盖该文件,该函数成功,并且最后一个错误代码设置为 ERROR_ALREADY_EXISTS (183)。
如果指定的文件不存在并且是有效路径,则创建一个新文件,函数成功,最后错误代码设置为零。
...
CREATE_NEW
1仅当它不存在时才创建一个新文件。
如果指定的文件存在,则函数失败并且最后一个错误代码设置为 ERROR_FILE_EXISTS (80)。
如果指定的文件不存在并且是可写位置的有效路径,则创建一个新文件。
例如:
string filename = name + ".txt";
int num = 0;
HANDLE hFile;
do
{
hFile = CreateFileA(filename.c_str(), 0, 0, NULL, CREATE_NEW, 0, NULL);
if ((hFile == INVALID_HANDLE_VALUE) && (GetLastError() == ERROR_FILE_EXISTS))
filename = name + to_string(num++) + ".txt";
else
break;
}
while (true);
if (hFile != INVALID_HANDLE_VALUE)
{
cout << "Created new file at: " << filename << endl;
// use hFile as needed...
CloseHandle(hFile);
}
else
{
DWORD errCode = GetLastError();
cerr << "Unable to create new file at: " << filename << ". Error " << errCode << endl;
// error handling...
}
推荐阅读
- c - 哈希集的交集和并集
- html - CSS过渡不是双向动画
- mysql - 表在程序中指定了两次,如何解决?
- jquery - 无法弄清楚如何获得此功能来仅更改与我单击的图像相关联的标题。总是更改所有标题
- javascript - jQuery 样式表不会加载
- c# - 为什么 TcpClient.Connected() 被 TcpListener 关闭后显示为 true?F#
- haskell - Haskell Lambda 案例或
- java - 为什么 xerces 向我显示“org.xml.sax.SAXParseException:发现以元素开头的无效内容”?
- php - php - 错误文本:字段列表中的未知列“”
- c - 带有 stdcall 的 MinGW 自定义导出函数名称