Ch 24: std::path路径操作
Path和PathBuf是Rust中处理路径的类型。它们是跨平台路径操作的基石。
- Path - 路径的引用(
&Path),不可变 - PathBuf - 拥有的路径,可变
路径在Unix和Windows上的表示不同:
- Unix:
/home/user/file.txt - Windows:
C:\Users\user\file.txt
2. Path创建与转换
Section titled “2. Path创建与转换”use std::path::{Path, PathBuf};
fn main() { // 从字面量创建Path let path: &Path = Path::new("hello/world");
// 从&str创建PathBuf let path_buf = PathBuf::from("hello/world");
// 从String创建PathBuf let path_buf2 = PathBuf::from(String::from("hello/world"));
println!("Path: {:?}", path); println!("PathBuf: {:?}", path_buf);}3. 路径组件
Section titled “3. 路径组件”use std::path::Path;
fn main() { let path = Path::new("home/user/document.txt");
// 迭代路径组件 for component in path.components() { println!("component: {:?}", component); } // 输出: // component: RootDir // component: Normal("home") // component: Normal("user") // component: Normal("document.txt")}4. 文件名与扩展名
Section titled “4. 文件名与扩展名”use std::path::Path;
fn main() { let path = Path::new("document.txt");
// file_name 获取文件名 println!("file_name: {:?}", path.file_name()); // 输出: Some("document.txt")
// extension 获取扩展名 println!("extension: {:?}", path.extension()); // 输出: Some("txt")
// file_stem 获取文件名(不含扩展名) println!("file_stem: {:?}", path.file_stem()); // 输出: Some("document")}5. 父路径
Section titled “5. 父路径”use std::path::Path;
fn main() { let path = Path::new("home/user/document.txt");
// parent 获取父路径 println!("parent: {:?}", path.parent()); // 输出: Some("home/user")
// ancestors 返回所有祖先路径 for ancestor in path.ancestors() { println!("ancestor: {:?}", ancestor); } // 输出: "home/user", "home", ""
// is_root 检查是否是根路径 println!("is_root: {}", path.is_root());}6. strip_prefix去除前缀
Section titled “6. strip_prefix去除前缀”use std::path::Path;
fn main() { let full_path = Path::new("/home/user/document.txt");
// 去除前缀 let base = Path::new("/home/user");
if let Ok(relative) = full_path.strip_prefix(base) { println!("相对路径: {:?}", relative); // 输出: "document.txt" }
// strip_prefix返回的是&Path let relative = full_path.strip_prefix("/home").unwrap(); println!("去除/home后: {:?}", relative); // 输出: "user/document.txt"}7. join拼接路径
Section titled “7. join拼接路径”use std::path::Path;
fn main() { let base = Path::new("/home/user");
// join 拼接路径 let full = base.join("documents"); let full2 = base.join("documents").join("file.txt");
println!("拼接1: {:?}", full); // 输出: "/home/user/documents"
println!("拼接2: {:?}", full2); // 输出: "/home/user/documents/file.txt"
// PathBuf的push let mut path_buf = PathBuf::from("/home"); path_buf.push("user"); path_buf.push("file.txt");
println!("push后: {:?}", path_buf);}8. starts_with与ends_with
Section titled “8. starts_with与ends_with”use std::path::Path;
fn main() { let path = Path::new("/home/user/file.txt");
// starts_with 检查路径是否以指定前缀开始 println!("starts with /home: {}", path.starts_with("/home")); println!("starts with /tmp: {}", path.starts_with("/tmp"));
// ends_with 检查路径是否以指定后缀结束 println!("ends with file.txt: {}", path.ends_with("file.txt")); println!("ends with .txt: {}", path.ends_with(".txt"));}9. 转换为字符串
Section titled “9. 转换为字符串”use std::path::Path;
fn main() { let path = Path::new("hello/world");
// to_str 转换为&str(可能失败) if let Some(s) = path.to_str() { println!("to_str: {}", s); }
// to_string_lossy 转换为String,替换无效字符 let lossy = path.to_string_lossy(); println!("to_string_lossy: {}", lossy);
// display 获取可以显示的引用 let path = Path::new("/home/user/中文.txt"); println!("display: {}", path.display());}10. PathBuf可变操作
Section titled “10. PathBuf可变操作”use std::path::PathBuf;
fn main() { let mut path = PathBuf::from("/home/user");
// push 添加路径组件 path.push("documents"); println!("push后: {:?}", path);
// pop 移除最后一个组件 path.pop(); println!("pop后: {:?}", path);
// set_file_name 设置文件名 path = PathBuf::from("/home/user/old.txt"); path.set_file_name("new.txt"); println!("set_file_name后: {:?}", path);
// set_extension 设置扩展名 path = PathBuf::from("/home/user/file.txt"); path.set_extension("md"); println!("set_extension后: {:?}", path);
// clear 清空 path.clear(); println!("clear后: {:?}", path);}11. 跨平台路径
Section titled “11. 跨平台路径”use std::path::Path;
fn main() { // Unix路径 let unix_path = Path::new("/home/user/file.txt"); println!("Unix路径组件数: {}", unix_path.components().count());
// Windows路径 #[cfg(windows)] { let win_path = Path::new("C:\\Users\\user\\file.txt"); println!("Windows路径组件数: {}", win_path.components().count()); }}12. 实用示例
Section titled “12. 实用示例”12.1 处理文件扩展名
Section titled “12.1 处理文件扩展名”use std::path::Path;
fn main() { fn process_image(path: &Path) { if let Some(ext) = path.extension() { match ext.to_string_lossy().as_ref() { "jpg" | "jpeg" => println!("JPEG图片"), "png" => println!("PNG图片"), "gif" => println!("GIF图片"), _ => println!("未知格式"), } } }
process_image(Path::new("photo.jpg")); process_image(Path::new("image.png"));}12.2 规范化路径
Section titled “12.2 规范化路径”use std::path::Path;
fn main() { let messy = Path::new("./home/user/../user/./file.txt");
// components会返回规范化后的组件 let components: Vec<_> = messy.components() .filter(|c| !matches!(c, std::path::Component::CurDir)) .collect();
println!("规范化组件: {:?}", components);}13. Path与File操作
Section titled “13. Path与File操作”use std::fs;use std::path::Path;
fn main() -> std::io::Result<()> { let path = Path::new("test.txt");
// File::open 接受 AsRef<Path> let file = fs::File::open(&path)?; println!("文件打开: {:?}", file);
// fs::read 接受 AsRef<Path> let content = fs::read(&path)?; println!("文件大小: {} bytes", content.len());
// fs::write 接受 AsRef<Path> fs::write(&path, "hello")?;
// 清理 fs::remove_file(&path)?;
Ok(())}14. Path方法汇总
Section titled “14. Path方法汇总”| 方法 | 说明 |
|---|---|
new(s) | 从字符串创建Path |
file_name() | 获取文件名 |
extension() | 获取扩展名 |
file_stem() | 获取文件名(不含扩展名) |
parent() | 获取父路径 |
ancestors() | 返回所有祖先路径 |
components() | 返回路径组件迭代器 |
strip_prefix(p) | 去除前缀 |
join(p) | 拼接路径 |
starts_with(p) | 检查前缀 |
ends_with(p) | 检查后缀 |
is_absolute() | 是否是绝对路径 |
is_relative() | 是否是相对路径 |
to_str() | 转换为&str |
to_string_lossy() | 转换为String |
display() | 获取Display引用 |
15. 总结
Section titled “15. 总结”今天我们学习了std::path路径操作:
- Path/PathBuf - 路径的引用类型和拥有类型
- components - 迭代路径组件
- file_name/extension - 获取文件名和扩展名
- parent/ancestors - 获取父路径
- strip_prefix - 去除路径前缀
- join/push - 路径拼接
- starts_with/ends_with - 前缀后缀检查
- set_file_name/set_extension - 设置文件名/扩展名
Path和PathBuf是Rust中处理文件路径的标准方式,提供了跨平台的路径操作能力。