首页 > 解决方案 > 如果发现任何重复项,如何创建修改的文件

问题描述

我希望通过用户提供的名称创建一个文件。如果文件名已经存在,我希望在创建之前自动修改文件名。

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

标签: c++filewinapidirectory

解决方案


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

推荐阅读