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 会将其解释为驱动器上当前目录的相对路径。即P:
andP:\
可以引用不同的位置,并且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());
}
推荐阅读
- javascript - JavaScript unicode 感知字符串切片
- regression - 即使 val_loss 较低,我使用 LSTM 的回归 NN 的输出也是错误的
- python - python - 如何在没有for循环的情况下有效地计算欧几里得距离矩阵?
- mysql - 如何用 SQL 替换单个列中的多个值?
- f# - F# 中的嵌套 monad 绑定
- python - 如何从 requirements.txt 文件中选择特定版本
- javascript - 在有和没有 concat 的情况下过滤不同值的结果
- c++ - 在 Linux 中通过 casablanca / cpprest 使用 TLS 客户端身份验证
- c++ - 如何保持 2 台主机之间的 UDP 套接字连接打开
- arrays - Matlab中的方括号运算符在其两个值之间没有逗号