Как создать файл, который будет изменен, если найдены дубликаты - PullRequest
0 голосов
/ 07 апреля 2020

Я хочу, чтобы файл создавался по имени, заданному пользователем. Если имя файла уже существует, я хочу, чтобы имя файла было автоматически изменено перед созданием.

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

1-й запуск программы

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

2-й запуск программы

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

3-я программа запуска

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

1 Ответ

2 голосов
/ 08 апреля 2020

Использование 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...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...