31 个稳定版本
3.1.1 | 2023 年 9 月 9 日 |
---|---|
3.1.0 | 2023 年 5 月 7 日 |
3.0.14 | 2022 年 10 月 14 日 |
3.0.13 | 2022 年 4 月 7 日 |
1.1.3 | 2018 年 11 月 15 日 |
在 文件系统 中排名 #8
每月下载 227,127 次
在 255 个 Crates 中使用(直接使用 164 个)
42KB
506 行
路径绝对化
这是一个用于扩展 Path
和 PathBuf
的库,以便获取绝对路径并删除包含的点。
absolutize
方法和 canonicalize
方法的区别在于,absolutize
不关心文件是否存在以及文件的真实内容。
请阅读以下示例以了解解析规则。
示例
您可以使用两种方法。
absolutize
获取绝对路径。
即使路径已经是绝对路径(这意味着在类 Unix 系统上以 MAIN_SEPARATOR
开头),路径中的点也会被解析。
use std::path::Path;
use path_absolutize::*;
let p = Path::new("/path/to/123/456");
assert_eq!("/path/to/123/456", p.absolutize().unwrap().to_str().unwrap());
use std::path::Path;
use path_absolutize::*;
let p = Path::new("/path/to/./123/../456");
assert_eq!("/path/to/456", p.absolutize().unwrap().to_str().unwrap());
如果路径以单个点开头,则点表示您的程序的 当前工作目录(CWD)。
use std::path::Path;
use std::env;
use path_absolutize::*;
let p = Path::new("./path/to/123/456");
assert_eq!(Path::join(env::current_dir().unwrap().as_path(), Path::new("path/to/123/456")).to_str().unwrap(), p.absolutize().unwrap().to_str().unwrap());
如果路径以一对点开头,则点表示 CWD 的父目录。如果 CWD 是 根目录,则父目录仍然是 根目录。
use std::path::Path;
use std::env;
use path_absolutize::*;
let p = Path::new("../path/to/123/456");
let cwd = env::current_dir().unwrap();
let cwd_parent = cwd.parent();
match cwd_parent {
Some(cwd_parent) => {
assert_eq!(Path::join(&cwd_parent, Path::new("path/to/123/456")).to_str().unwrap(), p.absolutize().unwrap().to_str().unwrap());
}
None => {
assert_eq!(Path::join(Path::new("/"), Path::new("path/to/123/456")).to_str().unwrap(), p.absolutize().unwrap().to_str().unwrap());
}
}
不以 MAIN_SEPARATOR
、单个点 和 双点 开头的路径,在使用 absolutize
方法时将表现得像以单个点开头。
use std::path::Path;
use std::env;
use path_absolutize::*;
let p = Path::new("path/to/123/456");
assert_eq!(Path::join(env::current_dir().unwrap().as_path(), Path::new("path/to/123/456")).to_str().unwrap(), p.absolutize().unwrap().to_str().unwrap());
use std::path::Path;
use std::env;
use path_absolutize::*;
let p = Path::new("path/../../to/123/456");
let cwd = env::current_dir().unwrap();
let cwd_parent = cwd.parent();
match cwd_parent {
Some(cwd_parent) => {
assert_eq!(Path::join(&cwd_parent, Path::new("to/123/456")).to_str().unwrap(), p.absolutize().unwrap().to_str().unwrap());
}
None => {
assert_eq!(Path::join(Path::new("/"), Path::new("to/123/456")).to_str().unwrap(), p.absolutize().unwrap().to_str().unwrap());
}
}
从给定的当前工作目录开始
使用 absolutize_from
函数,您可以提供相对路径应该解析的当前工作目录。
use std::env;
use std::path::Path;
use path_absolutize::*;
let p = Path::new("../path/to/123/456");
let cwd = env::current_dir().unwrap();
println!("{}", p.absolutize_from(cwd).unwrap().to_str().unwrap());
absolutize_virtually
仅在特定目录下获取绝对路径。
即使路径已经是绝对路径(这意味着在类 Unix 系统上以 MAIN_SEPARATOR
开头),路径中的点也会被解析。
use std::path::Path;
use path_absolutize::*;
let p = Path::new("/path/to/123/456");
assert_eq!("/path/to/123/456", p.absolutize_virtually("/").unwrap().to_str().unwrap());
use std::path::Path;
use path_absolutize::*;
let p = Path::new("/path/to/./123/../456");
assert_eq!("/path/to/456", p.absolutize_virtually("/").unwrap().to_str().unwrap());
每个绝对路径都应该位于虚拟根目录下。
use std::path::Path;
use std::io::ErrorKind;
use path_absolutize::*;
let p = Path::new("/path/to/123/456");
assert_eq!(ErrorKind::InvalidInput, p.absolutize_virtually("/virtual/root").unwrap_err().kind());
每个相对路径都应该位于虚拟根目录下。
use std::path::Path;
use std::io::ErrorKind;
use path_absolutize::*;
let p = Path::new("./path/to/123/456");
assert_eq!(ErrorKind::InvalidInput, p.absolutize_virtually("/virtual/root").unwrap_err().kind());
use std::path::Path;
use std::io::ErrorKind;
use path_absolutize::*;
let p = Path::new("../path/to/123/456");
assert_eq!(ErrorKind::InvalidInput, p.absolutize_virtually("/virtual/root").unwrap_err().kind());
不以下列开头的路径:MAIN_SEPARATOR
、单个点 和 双点,在 absolutize_virtually
方法使用后将被定位在虚拟根目录下。
use std::path::Path;
use path_absolutize::*;
let p = Path::new("path/to/123/456");
assert_eq!("/virtual/root/path/to/123/456", p.absolutize_virtually("/virtual/root").unwrap().to_str().unwrap());
use std::path::Path;
use path_absolutize::*;
let p = Path::new("path/to/../../../../123/456");
assert_eq!("/virtual/root/123/456", p.absolutize_virtually("/virtual/root").unwrap().to_str().unwrap());
缓存
默认情况下,absolutize
方法和 absolutize_virtually
方法在每次操作时都会创建一个新的 PathBuf
实例,该实例对应当前工作目录(CWD)。虽然这允许程序在运行时安全地通过自身(例如,使用 std::env::set_current_dir
函数)或外部控制(例如,使用 gdb 调用 chdir
)来更改 CWD,但在大多数情况下我们并不需要这样做。
为了提高解析路径的性能,这个库提供了三种缓存 CWD 的方法。
once_cell_cache
启用 once_cell_cache
功能可以让这个库使用 once_cell
来缓存 CWD。它是线程安全的,并且不需要修改任何代码,但是一旦 CWD 被缓存,它就不能在运行时再更改。
[dependencies.path-absolutize]
version = "*"
features = ["once_cell_cache"]
lazy_static_cache
启用 lazy_static_cache
功能可以让这个库使用 lazy_static
来缓存 CWD。它是线程安全的,并且不需要修改任何代码,但是一旦 CWD 被缓存,它就不能在运行时再更改。
[dependencies.path-absolutize]
version = "*"
features = ["lazy_static_cache"]
unsafe_cache
启用 unsafe_cache
功能可以让这个库使用一个可变静态变量来缓存 CWD。它允许程序通过自身在运行时更改 CWD,但它不是线程安全的。
您需要使用 update_cwd
函数首先初始化 CWD。该函数还应在 CWD 发生更改后用于更新 CWD。
[dependencies.path-absolutize]
version = "*"
features = ["unsafe_cache"]
use std::path::Path;
use path_absolutize::*;
unsafe {
update_cwd();
}
let p = Path::new("./path/to/123/456");
println!("{}", p.absolutize().unwrap().to_str().unwrap());
std::env::set_current_dir("/").unwrap();
unsafe {
update_cwd();
}
println!("{}", p.absolutize().unwrap().to_str().unwrap());
基准测试
无缓存
cargo bench
once_cell_cache
cargo bench --features once_cell_cache
lazy_static_cache
cargo bench --features lazy_static_cache
unsafe_cache
cargo bench --features unsafe_cache
Crates.io
https://crates.io/crates/path-absolutize
文档
https://docs.rs/path-absolutize
许可证
依赖项
~83KB