Rust中如何判断两个Path路径是否属于同一文件系统
Rust如何判断两个Path是否处于同一文件系统
给定两个
Path结构,我该如何判断二者是否处于同一个文件系统下?我需要使用std::fs::rename移动文件,但我只希望在源路径和目标路径位于同一文件系统时才执行重命名操作,否则重命名操作必然会失败。在bash中我可以使用stat -c "%d" PATH实现该需求,Rust提供了std::fs::metadata,但它似乎不会返回fsid。
解决方案
标准库的std::fs::Metadata跨平台通用接口没有直接暴露文件系统ID,但可以通过各平台的扩展特征实现需求,无需引入第三方依赖:
- 类Unix系统(Linux、macOS、BSD等)可以调用
std::os::unix::fs::MetadataExt提供的dev()方法,返回值对应stat命令输出的%d(设备ID,可唯一标识一个文件系统) - Windows系统可以调用
std::os::windows::fs::MetadataExt提供的volume_serial_number()方法,返回值为卷序列号,值相同即代表路径处于同一文件系统
你可以直接封装一个跨平台的判断函数:
use std::fs; use std::io; use std::path::Path; #[cfg(unix)] pub fn is_same_filesystem(src: &Path, dst: &Path) -> io::Result<bool> { use std::os::unix::fs::MetadataExt; let src_metadata = fs::metadata(src)?; let dst_metadata = fs::metadata(dst)?; Ok(src_metadata.dev() == dst_metadata.dev()) } #[cfg(windows)] pub fn is_same_filesystem(src: &Path, dst: &Path) -> io::Result<bool> { use std::os::windows::fs::MetadataExt; let src_metadata = fs::metadata(src)?; let dst_metadata = fs::metadata(dst)?; Ok(src_metadata.volume_serial_number() == dst_metadata.volume_serial_number()) }
注意事项
如果目标路径是还未创建的新路径,你需要先获取目标路径父目录的元数据进行比对,避免读取不存在路径的元数据触发报错。
如果不想自行封装跨平台逻辑,也可以直接使用社区成熟的第三方库如same-file,内部已经做好了跨平台兼容处理。
内容的提问来源于stack exchange,提问作者Troels Arvin
相关产品推荐
相关产品推荐

