rust - 处理可能是驱动器号或连接到其他路径的路径的正确方法是什么?

标签 rust

使用以下程序:

use std::path::Path;

fn main() {
    println!("{:?}", Path::new("P:").join("A_B_C\\D\\E\\F\\G.hij"));
}

POSIX 会给你:

"P:/A_B_C\\D\\E\\F\\G.hij"

但是 Windows 会给你:

"P:A_B_C\\D\\E\\F\\G.hij"

后者不被认为是预期路径,至少 std::fs::copy 是这样。

同样的例子:

fn my_function(p: &Path) -> PathBuf {
    p.join("Temp")
}

最佳答案

首先,请注意,当您指定不带尾部斜杠符号的驱动器号时,Windows API 将其解释为驱动器上当前目录的相对路径。 IE。 P:P:\ 可以引用不同的位置,P:file.txt 是一个有效路径,表示 P:\current\dir\file.txt。您可以通过更改目录并从命令提示符 dir P:dir P:\ 调用来验证它。

如果您确定要将“P:”解释为根路径,那么您可能应该手动检测它并添加根斜杠,但我认为这是一种不好的做法。

要严格解释路径前缀并构建绝对路径前缀,您可以使用 Path::canonicalize()方法,但请记住,它仅适用于目标操作系统中实际存在的驱动器/路径。

use std::path::{Path, PathBuf};

fn canonical_join<P: AsRef<Path>>(a: P, b: P) -> PathBuf {
    let a = a.as_ref();
    a.canonicalize()
    .unwrap_or(PathBuf::from(a))
    .join(b)
}

fn main() {
    println!("{}", canonical_join("C:", "dir\\file.ext").display());
    println!("{}", canonical_join("C:\\", "dir\\file.ext").display());
    println!("{}", canonical_join("C:/", "dir\\file.ext").display());
}

关于rust - 处理可能是驱动器号或连接到其他路径的路径的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51297055/

相关文章:

rust - 为什么没有为 `Clone` 实现 `fn(&T)` 特征?

rust - 使用 transmute 实现可变迭代器以避免与不可变对应物的代码重复是否安全?

rust - 编译错误 len 作为 const fn 还不稳定

rust - 选择换行符在多行字符串文字中的位置

testing - cargo test --release 导致堆栈溢出。为什么没有货台?

generics - 接受受多个特征中的任何一个约束的参数的函数

rust - 高效提取前缀子串

rust - 分配数据以传递给 FFI 调用的正确方法是什么?

rust - 如何用 Vec 支持 HashMap

rust - 有没有更简短的方法来编写采用和返回闭包的函数签名?