CopyFile не может найти файл, пока я могу открыть его из fopen

Я пытаюсь создать программу, которая создает резервную копию папки. Проблема в том, что когда я пытаюсь использовать функцию CopyFile, я получаю ошибку 2 (FILE_NOT_FOUND), но я могу открыть файл, используя fopen и точно такой же путь. Я также использую формат utf-8.


void Folder::copy_files(std::string destination) {

    bool error = false;
    std::string destinationpath = destination;
    for (std::string i : Get_files_paths()) {
        std::string destinationpath = destination;
        destinationpath.append(split_file_folder_name(i));


#ifdef DEBUG
        char str[100];
        const char* floc_cstr = i.c_str();
        LPCTSTR floc = (LPCTSTR)floc_cstr;
        printf("\t[DEBUG]FILE_LOC_PATH: %s\n", floc_cstr);
        std::cout << "\t[DEBUG]memory loc" << floc << std::endl;
#pragma warning(disable : 4996)
        FILE* fp = fopen(floc_cstr, "r");
        if (fp == NULL) {
            printf("file not found");
            exit(1);
        }
        else {
            printf("file found \n");
            fscanf(fp, "%s", str);
            printf("%s", str);
        }
        fclose(fp);
        print_last_error(GetLastError());
#endif
        error = CopyFile(floc , (LPCTSTR)destinationpath.c_str(), false);
        if (error == false) {
            print_last_error(GetLastError());
        }
    }

}

Из этого кода я должен ожидать, что скопирую файл, но получаю FILE_NOT_FOUND. Кто-нибудь знает, почему это происходит? (если вам нужна какая-либо другая часть кода, дайте мне знать)


person Nikos Issaris    schedule 03.07.2019    source источник
comment
Проверьте, существует ли путь назначения. CopyFile не будет создавать папку или подпапки.   -  person SolidMercury    schedule 03.07.2019
comment
Путь назначения существует. Также, если путь назначения не существует, номер ошибки равен 3 (PATH_NOT_FOUND).   -  person Nikos Issaris    schedule 03.07.2019
comment
Вы можете увидеть файл с помощью проводника?   -  person Ted Lyngmo    schedule 03.07.2019
comment
Напечатайте floc непосредственно перед CopyFile и проверьте путь.   -  person SolidMercury    schedule 03.07.2019
comment
@TedLyngmo да, и я также могу открыть его с помощью fopen и получить его содержимое   -  person Nikos Issaris    schedule 03.07.2019
comment
@NikosIssaris Хорошо, просто проверяю. В Windows есть слой Compatibility Files/VirtualStore, который, когда он активен, может испортить ситуацию, так что вы сможете открывать файлы из программы, используя определенный путь, но он будет невидим для других программ, поскольку реальный путь скрыт: файлы совместимости.   -  person Ted Lyngmo    schedule 03.07.2019
comment
Виртуальный магазин @TedLyngmo почти пуст. даже если программа запущена.   -  person Nikos Issaris    schedule 03.07.2019
comment
Приведение от const char* к LPCTSTR заставляет меня подозревать, что ваш LPCTSTR на самом деле является const wchar_t*. Попробуйте использовать это и посмотрите, что произойдет: CopyFileA(floc_cstr, destinationpath.c_str(), false);   -  person Ted Lyngmo    schedule 03.07.2019
comment
@TedLyngmo это изменение работает для файлов, имена которых состоят из английских символов, но не работает для других файлов (греческих символов)   -  person Nikos Issaris    schedule 03.07.2019
comment
Является ли ваш путь к файлу юникодным или многобайтным?   -  person Nina    schedule 03.07.2019
comment
@NikosIssaris Ах ... Хорошо, тогда вам, вероятно, следует использовать std::wstring вместо этого в своем проекте. Кроме того, взгляните на std::filesystem::file_copy с аргументами std::filesystem::path, которые должны работать как есть с L"paths" и простым "paths".   -  person Ted Lyngmo    schedule 03.07.2019
comment
@Нина да, он содержит английские и греческие символы, в начале программы у меня есть std::setlocale(LC_ALL, "en_US.utf8"); std::locale::global(std::locale("en_US.utf8"));   -  person Nikos Issaris    schedule 03.07.2019
comment
@NikosIssaris Затем используйте CopyFileW и std::wstring. Вы все еще можете использовать std::string, но вам определенно следует использовать CopyFileW.   -  person Nina    schedule 03.07.2019


Ответы (1)


Спасибо за помощь в комментариях, решение состояло в том, чтобы использовать std::filesystem::copy_file(i,destinationpath); вместо
CopyFile(floc , (LPCTSTR)destinationpath.c_str(), false); Использование wstring не было необходимо. Итак, код сейчас такой:

void Folder::copy_files(std::string destination) {
    const char* floc_cstr = NULL;
    bool error = false;
    std::string destinationpath;
    for (std::string i : Get_files_paths()) {
        try {
            destinationpath = destination;
            destinationpath.append(split_file_folder_name(i));
            error = fs::copy_file(i, destinationpath);
            if (error == false) {
                print_last_error(GetLastError());
            }
        }
        catch(std::exception e) {
#ifdef DEBUG
            std::cout << "[DEBUG]" << e.what() <<std::endl;
#endif
            std::cout << "file exist\n";
            continue;
        }
    }
}
person Nikos Issaris    schedule 03.07.2019
comment
Отлично, что получилось. Обратите внимание, что <filesystem> имеет много полезных функций. Я не уверен, что делает split_file_folder_name в вашем коде, но он может уже так или иначе существовать в std::filesystem::path - person Ted Lyngmo; 03.07.2019