为何向Windows API函数FindFirstFileA传入C:*会列出当前目录文件?
关于Windows API
FindFirstFileA路径解析的行为疑惑 调试Rust的std::fs::read_dir函数时发现异常,于是基于Windows底层APIFindFirstFileA编写了测试程序,发现以下行为:
- 传入
C:\*时,正常列出C盘根目录的文件 - 传入
C:*时,却列出当前工作目录的内容,与传入.\*的效果完全一致
原本以为C:*属于无效路径,应该像传入NonExistentDirectory那样返回ERROR_FILE_NOT_FOUND错误,但实际并非如此。想知道这是有意设计还是未定义行为,查阅FindFirstFileA的备注文档后未找到相关说明。
演示代码
// FindFirstFileACPPTest.cpp #include <windows.h> #include <iostream> #include <string> #include <vector> int main() { std::vector<std::string> directories = { "C:\\", "C:", "NonExistentDirectory" }; for (const auto& directory : directories) { std::string searchPath = directory + "*"; WIN32_FIND_DATAA fileData; HANDLE searchHandle = FindFirstFileA(searchPath.c_str(), &fileData); std::cout << std::endl; if (searchHandle == INVALID_HANDLE_VALUE) { std::cout << "Error: Could not find files in directory " << directory << std::endl; continue; } std::cout << "Directory: " << directory << std::endl; do { if (fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { std::cout << "[DIR] " << fileData.cFileName << std::endl; } else { std::cout << "[FILE] " << fileData.cFileName << std::endl; } } while (FindNextFileA(searchHandle, &fileData)); FindClose(searchHandle); } return 0; }
输出结果
Directory: C:\ [DIR] $Recycle.Bin [DIR] AMD [DIR] Documents and Settings [DIR] Drivers [FILE] DumpStack.log.tmp [DIR] Licenses [FILE] pagefile.sys [DIR] PerfLogs [DIR] Program Files [DIR] Program Files (x86) [DIR] ProgramData [DIR] Recovery [FILE] swapfile.sys [DIR] System Volume Information [DIR] Users [DIR] Windows Directory: C: [DIR] . [DIR] .. [FILE] FindFirstFileACPPTest.cpp [FILE] FindFirstFileACPPTest.vcxproj [FILE] FindFirstFileACPPTest.vcxproj.filters [FILE] FindFirstFileACPPTest.vcxproj.user [DIR] x64 Error: Could not find files in directory NonExistentDirectory
解答
这是Windows文件系统路径解析的有意设计,属于DOS时代遗留的兼容规则:
C:\明确指向C盘的根目录,加上*后会检索该目录下的所有文件C:不带反斜杠时,代表的是C盘的进程级当前工作目录——Windows系统中,每个进程会为每个盘符维护独立的当前工作目录,默认是该盘符的根目录,但可通过命令行(如cd C:\some\path)或API调用修改。当你传入C:*时,系统会将其解析为「C盘当前工作目录下的所有文件」,这就是它会列出当前项目目录文件的原因(你的程序运行时,C盘的当前工作目录被设置为了项目所在路径)。
这种行为并非未定义行为,而是Windows路径解析的通用规则,适用于所有文件操作API,只是FindFirstFileA的文档未单独标注该场景。
内容的提问来源于stack exchange,提问作者Malted_Wheaties
相关产品推荐
相关产品推荐

