getdrivetype 是 windows 下判断可移动驱动器最可靠方式,传入规范化的根路径(如 "f:"),返回 drive_removable 即表示可移动;linux 依赖 /sys/block/*/removable 等内核接口,macos 使用 diskutil info -plist;跨平台应避免布尔返回,改用枚举类型并缓存结果。

Windows下用 GetDriveType 判断可移动驱动器类型
直接调用 Windows API 的 GetDriveType 是最可靠的方式。它不依赖文件系统挂载状态或权限,只看驱动器物理/逻辑分类。传入形如 "F:\" 或 "F:" 的根路径(注意末尾反斜杠或冒号),返回值为 DRIVE_REMOVABLE 即表示可移动媒体。
常见错误是传入非根路径(如 "F:\data\test.txt"),这时函数返回 DRIVE_NO_ROOT_DIR;或者没做路径规范化,比如传 "f:" 小写盘符——虽然多数情况能识别,但文档未保证大小写无关,建议统一转大写再截取根路径。
- 先用
PathStripToRoot(shlwapi.h)或手动提取盘符+冒号+反斜杠 - 确保路径以
\开头的 UNC 路径不适用此函数(GetDriveType对 UNC 返回DRIVE_NO_ROOT_DIR) - 对网络驱动器映射(如
Z:指向 SMB 共享),该函数可能误报为DRIVE_REMOVABLE,需结合WNetGetConnection进一步验证
Linux/macOS 下靠 statfs 和挂载选项识别
Unix-like 系统没有“可移动媒体”原生概念,得从挂载行为和文件系统特征推断。核心思路是:查路径所在挂载点的 statfs 信息,再读 /proc/mounts(Linux)或 getmntinfo(macOS)确认挂载参数是否含 removable、hotpluggable 或设备节点是否在 /dev/sdX / /dev/disk2 等典型可移动设备路径下。
实际中更常用的是检查 /sys/block/*/removable(Linux):先用 realpath 获取路径对应块设备(如 /dev/sdb1),再读取 /sys/block/sdb/removable 文件内容是否为 "1"。macOS 则可用 diskutil info -plist 解析 XML 输出中的 WholeDisk 和 Internal 字段。
-
statfs本身不提供可移动性字段,仅用于定位挂载点 - 不要只依赖文件系统类型(如
vfat),U 盘可能格式化为ext4,SSD 也可能挂载为vfat - 普通用户可能无权读
/sys/block/,需降级 fallback 到挂载选项关键词匹配(如noauto,user组合出现频率较高)
跨平台封装时绕不开的语义差异
“可移动媒体”在不同系统上含义不同:Windows 关注硬件总线类型(USB/SATA 都可能是 removable),Linux 更强调热插拔能力和内核标记,macOS 则混用物理接口(Thunderbolt vs USB)和固件报告。这意味着同一设备在不同系统上可能得到不同判定结果。
例如一个 USB-C 接口的 NVMe 移动硬盘,在 Windows 上大概率是 DRIVE_REMOVABLE,Linux 可能因内核驱动未设 removable=1 而返回 0,macOS 则可能根据固件报告标记为 Internal=false 但 Virtual=false —— 这些细节无法用单一布尔值准确概括。
- 不要设计成 “is_removable() → bool”,至少暴露
enum { UNKNOWN, YES, NO, PROBABLY } - 缓存结果很重要:反复查
/sys/block/或调用diskutil开销不小,且设备插拔后状态会变,需监听 udev/diskarbitration 事件刷新 - 用户看到“可移动”预期是“安全弹出”,但程序不能替代
sync+udisks2弹出流程,判定只是前置条件
GetDriveType,或没处理符号链接导致 realpath 返回空。这些边界情况比算法逻辑更容易让判断失效。C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











