#path #absolute #dot #canonical #dedot

path-absolutize

扩展 PathPathBuf 的库,以便获取绝对路径并删除包含的点

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

Download history 48054/week @ 2024-04-22 41063/week @ 2024-04-29 44222/week @ 2024-05-06 51616/week @ 2024-05-13 46338/week @ 2024-05-20 44116/week @ 2024-05-27 40872/week @ 2024-06-03 49782/week @ 2024-06-10 52016/week @ 2024-06-17 41277/week @ 2024-06-24 52071/week @ 2024-07-01 62145/week @ 2024-07-08 60068/week @ 2024-07-15 51495/week @ 2024-07-22 51888/week @ 2024-07-29 57232/week @ 2024-08-05

每月下载 227,127
255 个 Crates 中使用(直接使用 164 个)

MIT 许可证

42KB
506

路径绝对化

CI

这是一个用于扩展 PathPathBuf 的库,以便获取绝对路径并删除包含的点。

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

许可证

MIT

依赖项

~83KB