使用 C++ 打印 C:\ 中的所有文件路径

Printing All The Files Path's In C:\ With C++

我试图打印 C: 中的所有文件路径。 但是我发现我遇到了权限错误。

void getAllFilesInDirectory(wstring directoryPath, vector<wstring> &files) {
    for (filesystem::directory_entry directory : filesystem::directory_iterator(directoryPath)) {


        if (GetFileAttributesW(directory.path().wstring().c_str()) == FILE_ATTRIBUTE_SYSTEM)
            continue;

        //Checking if directory.path is a file or a directory
        if (GetFileAttributesW(directory.path().wstring().c_str()) == FILE_ATTRIBUTE_NORMAL) {
            files.push_back(directory.path().wstring());
            wcout << "The path is " << directory.path().wstring() << endl;
            continue;
        }

        try {
            for (filesystem::directory_entry file : filesystem::recursive_directory_iterator(directory)) {


                if (GetFileAttributesW(file.path().wstring().c_str()) == FILE_ATTRIBUTE_DIRECTORY) {
                    continue;
                }


                wcout << "The path of the file is " << file.path().wstring() << endl;
                files.push_back(file.path().wstring());
            }
        } catch (exception &e) {
            wcout << "There is exception " << e.what() << " and the directory path is: " << directory.path().wstring()
                  << endl;

        }
    }
}

当我为函数提供一个常规目录(没有权限的目录)时,我的代码可以正常工作。

但是当我给他“C:\”时,他打印了一些路径后就退出了。

如果有人post他打印C盘所有路径的方法就好了

谢谢!

您在评论中说:

I want that my code will ignore files that he doesn't have access to them

std::filesystem::directory_iteratorstd::filesystem::recursive_directory_iterator 都有一个接受 std::filesystem::directory_options 枚举作为输入的构造函数,它有一个 skip_permission_denied 项目可用于该目的,例如:

void getAllFilesInDirectory(const wstring &directoryPath, vector<wstring> &files) {
    for (filesystem::directory_entry directory : filesystem::directory_iterator(directoryPath, filesystem::directory_options::skip_permission_denied)) {
        ...
        for (filesystem::directory_entry file : filesystem::recursive_directory_iterator(directory, filesystem::directory_options::skip_permission_denied)) {
            ...
        }
    }
}

附带说明一下,您可能需要考虑添加名称空间别名以缩短那些限定名称,例如:

namespace fs = std::filesystem;

for (fs::directory_entry directory : fs::directory_iterator(directoryPath, fs::directory_options::skip_permission_denied)) {
    ...
    for (fs::directory_entry file : fs::recursive_directory_iterator(directory, fs::directory_options::skip_permission_denied)) {
        ...
    }
}

此外,您对 GetFileAttributesW() 的使用是错误的。您没有检查错误,也没有考虑到文件夹和文件可以(通常确实)分配了多个属性。测试特定属性时使用 & (AND) 运算符。测试 FILE_ATTRIBUTE_NORMAL 属性并不是区分文件和文件夹的正确方法。改为测试 FILE_ATTRIBUTE_DIRECTORY 属性的 presence/lack。

试试这个:

namespace fs = std::filesystem;

void getAllFilesInDirectory(const wstring &directoryPath, vector<wstring> &files) {
    for (fs::directory_entry directory : fs::directory_iterator(directoryPath, fs::directory_options::skip_permission_denied)) {

        DWORD attrs = GetFileAttributesW(directory.path().wstring().c_str());

        if (attrs == INVALID_FILE_ATTRIBUTES) {
            DWORD err = GetLastError();
            wcerr << "Error " << err << " getting attributes for path " << directory.path().wstring() << endl;
            continue;
        }

        if (attrs & FILE_ATTRIBUTE_SYSTEM)
            continue;

        //Checking if directory.path is a file or a directory
        if (attrs & ~FILE_ATTRIBUTE_DIRECTORY) {
            files.push_back(directory.path().wstring());
            wcout << "The path is " << directory.path().wstring() << endl;
            continue;
        }

        try {
            for (fs::directory_entry file : fs::recursive_directory_iterator(directory, fs::directory_options::skip_permission_denied)) {

                attrs = GetFileAttributesW(file.path().wstring().c_str());

                if (attrs == INVALID_FILE_ATTRIBUTES) {
                    DWORD err = GetLastError();
                    wcerr << "Error " << err << " getting attributes for path " << file.path().wstring() << endl;
                    continue;
                }

                if (attrs & FILE_ATTRIBUTE_DIRECTORY)
                    continue;

                wcout << "The path of the file is " << file.path().wstring() << endl;
                files.push_back(file.path().wstring());
            }
        } catch (const exception &e) {
            wcout << "There is exception " << e.what() << " and the directory path is: " << directory.path().wstring() << endl;
        }
    }
}