Linux C++项目迁Windows:sys/dir.h的Windows等效库求推荐
Linux sys/dir.h 的 Windows 等效方案
Linux 下的 sys/dir.h 主要提供目录遍历、目录结构查询等功能,Windows 没有直接对应的头文件,以下是最相近的替代方案:
1. 标准 C++ Filesystem 库(推荐)
从 C++17 开始,标准库引入了 <filesystem>,完全跨平台,能替代 sys/dir.h 的绝大多数核心功能(目录遍历、文件/目录属性判断等),无需依赖平台特定 API。
示例代码:
#include <filesystem> #include <iostream> namespace fs = std::filesystem; int main() { const std::string target_dir = "C:\\your\\target\\directory"; // 遍历目录下所有条目 for (const auto& entry : fs::directory_iterator(target_dir)) { std::cout << entry.path().string() << std::endl; // 判断条目类型 if (entry.is_directory()) { std::cout << " [目录]" << std::endl; } else if (entry.is_regular_file()) { std::cout << " [普通文件]" << std::endl; } } return 0; }
注意:需使用 VS2017 及以上版本,编译时开启 C++17 或更高标准。
2. Windows 原生 Win32 API
如果无法使用 C++17,可以直接调用 Windows 原生 API,核心头文件为 <windows.h>,关键函数包括 FindFirstFileW、FindNextFileW、FindClose。
示例代码:
#include <windows.h> #include <iostream> #include <wchar.h> void traverse_dir(const wchar_t* dir_path) { WIN32_FIND_DATAW find_data; HANDLE h_find = FindFirstFileW(dir_path, &find_data); if (h_find == INVALID_HANDLE_VALUE) { std::cerr << "目录查找失败" << std::endl; return; } do { // 跳过当前目录 "." 和上级目录 ".." if (wcscmp(find_data.cFileName, L".") == 0 || wcscmp(find_data.cFileName, L"..") == 0) { continue; } std::wcout << find_data.cFileName << std::endl; // 判断是否为目录 if (find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { std::wcout << L" [目录]" << std::endl; } else { std::wcout << L" [普通文件]" << std::endl; } } while (FindNextFileW(h_find, &find_data) != 0); FindClose(h_find); } int main() { // 注意路径末尾需要加通配符 "*" const wchar_t* target_dir = L"C:\\your\\target\\directory\\*"; traverse_dir(target_dir); return 0; }
3. 兼容性封装(最小化原代码修改)
如果希望保留 sys/dir.h 风格的接口(如 opendir、readdir、closedir),可以自行封装一层,内部调用 Windows API 或标准库,减少原代码的改动量。
示例封装:
#include <windows.h> #include <string> // 模拟 dirent 结构 struct dirent { char d_name[MAX_PATH]; }; // 模拟 DIR 指针 struct DIR { HANDLE h_find; WIN32_FIND_DATAW find_data; dirent entry; }; DIR* opendir(const char* dir_path) { std::wstring w_dir(dir_path, dir_path + strlen(dir_path)); w_dir += L"\\*"; DIR* dir = new DIR; dir->h_find = FindFirstFileW(w_dir.c_str(), &dir->find_data); if (dir->h_find == INVALID_HANDLE_VALUE) { delete dir; return nullptr; } // 跳过 "." 和 ".." while (wcscmp(dir->find_data.cFileName, L".") == 0 || wcscmp(dir->find_data.cFileName, L"..") == 0) { if (!FindNextFileW(dir->h_find, &dir->find_data)) { FindClose(dir->h_find); delete dir; return nullptr; } } // 宽字符转多字节 WideCharToMultiByte(CP_ACP, 0, dir->find_data.cFileName, -1, dir->entry.d_name, MAX_PATH, nullptr, nullptr); return dir; } dirent* readdir(DIR* dir) { if (!dir) return nullptr; dirent* curr_entry = &dir->entry; // 读取下一个条目 if (!FindNextFileW(dir->h_find, &dir->find_data)) { FindClose(dir->h_find); delete dir; return nullptr; } // 跳过特殊目录 while (wcscmp(dir->find_data.cFileName, L".") == 0 || wcscmp(dir->find_data.cFileName, L"..") == 0) { if (!FindNextFileW(dir->h_find, &dir->find_data)) { FindClose(dir->h_find); delete dir; return nullptr; } } WideCharToMultiByte(CP_ACP, 0, dir->find_data.cFileName, -1, dir->entry.d_name, MAX_PATH, nullptr, nullptr); return curr_entry; } void closedir(DIR* dir) { if (dir) { FindClose(dir->h_find); delete dir; } }
内容的提问来源于stack exchange,提问作者JKola1042
相关产品推荐
相关产品推荐

