gcc C++无法遍历C驱动器

dm7nw8vv  于 2023-08-06  发布在  其他
关注(0)|答案(2)|浏览(125)

我的任务是按文件名查找文件。搜索必须从C:\驱动器启动。当我在其他驱动器上测试我的功能时,比如D:\或A:\,一切都很好,但我试图用C:\驱动器来做,我使用的是g编译器,C 17,Windows操作系统。调用main.cpp中的函数

try {
        if (SearchFile::find_file(fs::path("C:\\"), fileName)) {
            return 0;
        }
    } catch (const fs::filesystem_error& e) {
        std::cerr << "Error accessing filesystem: " << e.what() << std::endl;
        std::cerr << "Exception path1: " << e.path1() << std::endl;
        std::cerr << "Exception path2: " << e.path2() << std::endl;
    }
    for(const auto& drive : drives){
        fs::path drivePath(drive);
        std::string driveLetter = drivePath.string().substr(0, 1);
        if (!(driveLetter == "C" || driveLetter == "c")) {
            if (SearchFile::find_file(drivePath, fileName)) {
                break;
            }
        }
    }

字符串
我的函数,位于SearchFile类中

void SearchFile::search_in_directory(const fs::path &drive, const std::string &fileName,
                                     std::atomic<bool> &foundFile, std::mutex &mutex) {
    try {

    for(const auto& file_iterator : fs::recursive_directory_iterator(drive,
                                                                     fs::directory_options::skip_permission_denied)){
            if(foundFile) return;
            if(file_iterator.is_regular_file() && file_iterator.path().filename() == fileName){
                std::lock_guard<std::mutex> lock(mutex);
                std::cout << file_iterator.path() << std::endl;
                foundFile = true;
                return;
            }

    }
    } catch (const fs::filesystem_error& e) {
        // Print the exception details for debugging
        std::cerr << drive.filename() << '\n';
        std::cerr << "File system exception: " << e.what() << std::endl;
        std::cerr << "Exception path1: " << e.path1() << std::endl;
        std::cerr << "Exception path2: " << e.path2() << std::endl;
    }
}
bool SearchFile::find_file(const std::filesystem::path &drive, const std::string &fileName) {
       adjust_priviledges();
    std::atomic<bool> found = false;
    std::vector<std::thread> threads;
    std::mutex mutex;

    try {
        for(const auto& file_iterator :
                fs::recursive_directory_iterator(drive, fs::directory_options::skip_permission_denied)){
            if (fs::is_symlink(file_iterator)) {
                continue;
            }
            if(found) break;
            if(fs::is_directory(file_iterator ) && threads.size() < MAX_THREADS ){

                threads.emplace_back(&search_in_directory, file_iterator.path(),
                                     fileName, std::ref(found), std::ref(mutex));

            } else if(file_iterator.is_regular_file() && file_iterator.path().filename() == fileName){
                std::lock_guard<std::mutex> lock(mutex);
                std::cout << file_iterator.path() << std::endl;
                found = true;
                break;
            }}
    } catch (const fs::filesystem_error& e) {

        std::cerr << "File system exception: " << e.what() << std::endl;
        std::cerr << "Exception path1111: " << e.path1() << std::endl;
        std::cerr << "Exception path2: " << e.path2() << std::endl;
    }

    for(auto& thread : threads){
        thread.join();
    }
    return found;
}


大多数时候我都是这样的:“文件系统异常:文件系统错误:无法递增递归目录迭代器:尝试运行程序时参数“”无效。我也尝试AdjustPriviledges,但它仍然没有解决问题。此外,我还试图以管理员身份运行它,并禁用Windows Defender,仍然没有结果。

g2ieeal7

g2ieeal71#

这里有一个使用Windows(特定于平台)FindFirstFileExFindNextFile函数的参数。

  • 您可以使用这些函数的Unicode变体(我不想说标准库是否这样做)。
  • 您可以使用神奇的FIND_FIRST_EX_LARGE_FETCH标志,它可以大大加快速度。
  • 您可以传递FindExInfoBasic标志,这会加快速度。
  • 对于找到的每个文件,您都将得到一个WIN32_FIND_DATA结构,其中包含相当多的有用信息(包括名称ofc)。
  • 有多种方法可以告诉Windows您希望返回哪些匹配项,这些方法可能会派上用场。
  • 您可以更好地控制发生错误时的操作(通常为ERROR_ACCESS_DENIED)。
  • 在Windows 10上,您可以处理长度超过MAX_PATH(260)个字符的路径,尽管在系统驱动器上不太可能有必要。

好好想想吧。这并不难,但您可能更希望代码是可移植的。正如其他人所说,摆脱所有这些线程。那面神奇的旗帜应该给予你所需要的表演。

mrfwxfqh

mrfwxfqh2#

这看起来很可疑:

threads.emplace_back(&search_in_directory, file_iterator.path(),
                                     fileName, std::ref(found),std::ref(mutex));

字符串
file_iterator.path()返回一个路径示例的引用,其生存期不长于file_iterator本身的生存期。它通过引用传递给另一个线程中的search_in_directory。路径示例甚至可以在线程启动之前被删除。
让我们在通过引用传递之前复制路径和字符串,并保证其生命周期。我们可以传递foundmutex作为引用
这样做:

auto path = file_iterator.path();
// capture path and FileName by value (make a copy)
// capture found and mutex by reference
std::thread t = [path, fileName, &found, &mutex] () {
   search_in_directory(path, fileName, found, mutex);
};
threads.push_back(std::move(t));


我不确定这是否是唯一的问题,但它肯定是一个问题。

相关问题