如何判断文件或文件夹是在SSD还是硬盘上?

Vio*_*ffe 8 c++ windows winapi

如何在 C 或 C++ 中以编程方式确定指定路径是在闪存 (SSD) 驱动器上还是在磁性硬盘驱动器上?我只对固定驱动器感兴趣,而不是可移动驱动器,尽管确定可移动驱动器的类型也很好。

我正在寻找一种解决方案来查询 Windows 对指定路径及其所在物理驱动器的看法。没有对标!另请注意,由于 SMR HDD,寻求 TRIM 支持并不是一个有效的方法。

Bar*_*ani 6

摘自《Old New Thing》文章:如何判断文件是否位于 SSD 上?

\n
\n

这利用了我们上次学到的技巧,您可以\n对卷进行存储查询,并且如果该卷具有单个范围,\n它将报告答案。

\n

我们\xe2\x80\x99 与其说是\xe2\x80\x99 是否位于SSD 驱动器上,不如\n检查寻道是否空闲。对于 SSD 来说确实如此,但对于 RAM 驱动器来说\xe2\x80\x99s 也是如此。但 RAM 驱动器甚至比 SSD 还要快,所以我认为 \xe2\x80\x99s 可以将它们视为 \xe2\x80\x9c 超级棒的 SSD\xe2\x80\x9d...

\n
\n

这是一个稍微修改的版本,不需要wil::unique_hfile原始文章中的类。

\n

如果路径无效,此实现不会抛出异常,它将报告无效路径或网络路径的非 SSD。

\n
#include <iostream>\n#include <Windows.h>\n\nHANDLE GetVolumeHandleForFile(const wchar_t* filePath)\n{\n    wchar_t volume_path[MAX_PATH];\n    if (!GetVolumePathName(filePath, volume_path, ARRAYSIZE(volume_path)))\n        return nullptr;\n\n    wchar_t volume_name[MAX_PATH];\n    if (!GetVolumeNameForVolumeMountPoint(volume_path,\n        volume_name, ARRAYSIZE(volume_name)))\n        return nullptr;\n\n    auto length = wcslen(volume_name);\n    if (length && volume_name[length - 1] == L\'\\\\\')\n        volume_name[length - 1] = L\'\\0\';\n\n    return CreateFile(volume_name, 0,\n        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,\n        nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr);\n}\n\nbool IsFileOnSsd(const wchar_t* file_path)\n{\n    bool is_ssd{ false };\n    HANDLE volume = GetVolumeHandleForFile(file_path);\n    if (volume == INVALID_HANDLE_VALUE)\n    { return false; /*invalid path! throw?*/ }\n\n    STORAGE_PROPERTY_QUERY query{};\n    query.PropertyId = StorageDeviceSeekPenaltyProperty;\n    query.QueryType = PropertyStandardQuery;\n    DWORD count;\n    DEVICE_SEEK_PENALTY_DESCRIPTOR result{};\n    if (DeviceIoControl(volume, IOCTL_STORAGE_QUERY_PROPERTY,\n        &query, sizeof(query), &result, sizeof(result), &count, nullptr))\n    { is_ssd = !result.IncursSeekPenalty; }\n    else { /*fails for network path, etc*/ }\n    CloseHandle(volume);\n    return is_ssd;\n}\n\nint main()\n{\n    std::wcout << IsFileOnSsd(L"C:\\\\") << "\\n";\n    std::wcout << IsFileOnSsd(L"D:\\\\") << "\\n";\n    return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n