47 个稳定版本
3.1.1 | 2023 年 9 月 9 日 |
---|---|
3.1.0 | 2023 年 5 月 7 日 |
3.0.18 | 2022 年 10 月 13 日 |
3.0.17 | 2022 年 4 月 7 日 |
1.1.9 | 2018 年 11 月 15 日 |
#76 在 文件系统
246,657 每月下载量
用于 270 个 Crates (13 个直接使用)
35KB
495 行
Path Dedot
这是一个用于扩展 Path
和 PathBuf
以解析包含点的路径的库。
请阅读以下示例以了解解析规则。
示例
如果路径以单个点开头,点表示程序的 当前工作目录 (CWD)。
use std::path::Path;
use std::env;
use path_dedot::*;
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.parse_dot().unwrap().to_str().unwrap());
如果路径以一对点开头,点表示 CWD 的父目录。如果 CWD 是 根目录,父目录仍然是 根目录。
use std::path::Path;
use std::env;
use path_dedot::*;
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.parse_dot().unwrap().to_str().unwrap());
}
None => {
assert_eq!(Path::join(Path::new("/"), Path::new("path/to/123/456")).to_str().unwrap(), p.parse_dot().unwrap().to_str().unwrap());
}
}
除了开头,单点和双点也可以放在其他位置。单点表示无意义,将被忽略。双点表示父目录。
use std::path::Path;
use path_dedot::*;
let p = Path::new("/path/to/../123/456/./777");
assert_eq!("/path/123/456/777", p.parse_dot().unwrap().to_str().unwrap());
use std::path::Path;
use path_dedot::*;
let p = Path::new("/path/to/../123/456/./777/..");
assert_eq!("/path/123/456", p.parse_dot().unwrap().to_str().unwrap());
请注意,parse_dot
方法并不旨在获取 绝对路径。不以 MAIN_SEPARATOR
、单点和 双点 开头的路径在执行 parse_dot
方法后不会有每个点。
use std::path::Path;
use path_dedot::*;
let p = Path::new("path/to/../123/456/./777/..");
assert_eq!("path/123/456", p.parse_dot().unwrap().to_str().unwrap());
不在开头放置的 双点 不能获取超过原始路径的父目录。为什么?通过这个约束,你可以将绝对路径插入到开头作为虚拟根,以保护你的文件系统不被暴露。
use std::path::Path;
use path_dedot::*;
let p = Path::new("path/to/../../../../123/456/./777/..");
assert_eq!("123/456", p.parse_dot().unwrap().to_str().unwrap());
use std::path::Path;
use path_dedot::*;
let p = Path::new("/path/to/../../../../123/456/./777/..");
assert_eq!("/123/456", p.parse_dot().unwrap().to_str().unwrap());
从给定的当前工作目录开始
使用 parse_dot_from
函数,你可以提供相对路径应该从中解析的当前工作目录。
use std::env;
use std::path::Path;
use path_dedot::*;
let p = Path::new("../path/to/123/456");
let cwd = env::current_dir().unwrap();
println!("{}", p.parse_dot_from(cwd).unwrap().to_str().unwrap());
缓存
默认情况下,parse_dot
方法在其操作中每次都会创建一个新的 CWD 的 PathBuf
实例。开销是明显的。尽管它允许我们通过程序本身(例如,使用 std::env::set_current_dir
函数)或外部控制(例如,使用 gdb 调用 chdir
)安全地更改 CWD,但在大多数情况下我们不需要这样。
为了提高解析路径的性能,此crate提供了三种缓存当前工作目录(CWD)的方法。
once_cell_cache
启用once_cell_cache
特性可以让此crate使用once_cell
来缓存CWD。它是线程安全的,并且不需要修改任何代码,但一旦CWD被缓存,就无法在运行时更改。
[dependencies.path-dedot]
version = "*"
features = ["once_cell_cache"]
lazy_static_cache
启用lazy_static_cache
特性可以让此crate使用lazy_static
来缓存CWD。它是线程安全的,并且不需要修改任何代码,但一旦CWD被缓存,就无法在运行时更改。
[dependencies.path-dedot]
version = "*"
features = ["lazy_static_cache"]
unsafe_cache
启用unsafe_cache
特性可以让此crate使用可变的静态变量来缓存CWD。它允许程序通过自身在运行时更改CWD,但不是线程安全的。
您需要使用update_cwd
函数首先初始化CWD。该函数还应在CWD更改后用于更新CWD。
[dependencies.path-dedot]
version = "*"
features = ["unsafe_cache"]
use std::path::Path;
use path_dedot::*;
unsafe {
update_cwd();
}
let p = Path::new("./path/to/123/456");
println!("{}", p.parse_dot().unwrap().to_str().unwrap());
std::env::set_current_dir("/").unwrap();
unsafe {
update_cwd();
}
println!("{}", p.parse_dot().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-dedot
文档
许可证
依赖项
~51KB