我如何遍历目录并识别或省略 NTFS 连接(symlink-ish)
How can I iterate over a directory and identify or omit NTFS junctions (symlink-ish)
我有一些代码可以列出目录中的文件。对于 Windows 系统,我希望最终得到一个与您在 Windows 资源管理器中看到的相匹配的文件和文件夹列表。例如,当我在 Server 2016 上列出 C:\ 时,我想要 Users
文件夹而不是 Documents and Settings
连接。目前我得到了两者,没有明显的方法来区分它们。
我当前的代码如下所示:
boost::filesystem::directory_iterator itr(dir);
boost::filesystem::directory_iterator end;
Poco::SharedPtr<Poco::JSON::Array> fileList(new Poco::JSON::Array);
for (; itr != end; ++itr) {
boost::filesystem::path entryPath = itr->path();
Poco::File file(entryPath.string());
// ...
我尝试了 Poco isLink()
方法,但它 returns 对于路口是错误的。
我还尝试了 Poco::DirectoryIterator
,它提供与 Boost 相同的行为,以及 Poco::SortedDirectoryIterator
,它在读取 C:\
时总是抛出 File access error: sharing violation: \pagefile.sys
。
理想情况下,此代码应包括 Linux 和 MacOS 系统上的符号链接,同时忽略 Windows 上的连接。
这是我最终想到的。它不是一个完美的解决方案——它更像是一种启发式的方法,而不是一个合适的标识符——但它似乎对我的用例来说效果很好:
#ifdef _WIN32
#include <windows.h>
#endif
bool FileController::isNtfsJunction(const std::string& dirPath) const {
#ifdef _WIN32
DWORD attrs = GetFileAttributesA(dirPath.c_str());
if (INVALID_FILE_ATTRIBUTES == attrs) {
DWORD err = GetLastError();
logger.error("Could not determine if path is NTFS Junction: %s. Error: %s", dirPath, err);
return false;
}
return attrs & FILE_ATTRIBUTE_DIRECTORY &&
attrs & FILE_ATTRIBUTE_REPARSE_POINT &&
attrs & FILE_ATTRIBUTE_HIDDEN &&
attrs & FILE_ATTRIBUTE_SYSTEM;
#else
return false;
#endif
}
我有一些代码可以列出目录中的文件。对于 Windows 系统,我希望最终得到一个与您在 Windows 资源管理器中看到的相匹配的文件和文件夹列表。例如,当我在 Server 2016 上列出 C:\ 时,我想要 Users
文件夹而不是 Documents and Settings
连接。目前我得到了两者,没有明显的方法来区分它们。
我当前的代码如下所示:
boost::filesystem::directory_iterator itr(dir);
boost::filesystem::directory_iterator end;
Poco::SharedPtr<Poco::JSON::Array> fileList(new Poco::JSON::Array);
for (; itr != end; ++itr) {
boost::filesystem::path entryPath = itr->path();
Poco::File file(entryPath.string());
// ...
我尝试了 Poco isLink()
方法,但它 returns 对于路口是错误的。
我还尝试了 Poco::DirectoryIterator
,它提供与 Boost 相同的行为,以及 Poco::SortedDirectoryIterator
,它在读取 C:\
时总是抛出 File access error: sharing violation: \pagefile.sys
。
理想情况下,此代码应包括 Linux 和 MacOS 系统上的符号链接,同时忽略 Windows 上的连接。
这是我最终想到的。它不是一个完美的解决方案——它更像是一种启发式的方法,而不是一个合适的标识符——但它似乎对我的用例来说效果很好:
#ifdef _WIN32
#include <windows.h>
#endif
bool FileController::isNtfsJunction(const std::string& dirPath) const {
#ifdef _WIN32
DWORD attrs = GetFileAttributesA(dirPath.c_str());
if (INVALID_FILE_ATTRIBUTES == attrs) {
DWORD err = GetLastError();
logger.error("Could not determine if path is NTFS Junction: %s. Error: %s", dirPath, err);
return false;
}
return attrs & FILE_ATTRIBUTE_DIRECTORY &&
attrs & FILE_ATTRIBUTE_REPARSE_POINT &&
attrs & FILE_ATTRIBUTE_HIDDEN &&
attrs & FILE_ATTRIBUTE_SYSTEM;
#else
return false;
#endif
}