设计思路
- 定义结构体和枚举:定义
FileMetadata
结构体来存储文件元数据,包括文件名、文件大小和权限。同时定义权限枚举类型来表示文件的权限。
- 获取文件元数据函数:编写一个函数从文件系统获取文件元数据,并在出现错误时返回合适的错误类型。
- 错误处理:在主程序中调用该函数,并使用模式匹配处理不同类型的错误。通过实现
From
和Into
trait来优化错误处理代码,减少重复。
代码实现
use std::fs::Metadata;
use std::io;
use std::os::unix::fs::MetadataExt;
// 自定义权限枚举类型
#[derive(Debug)]
enum FilePermissions {
ReadOnly,
ReadWrite,
FullControl,
}
// FileMetadata结构体
#[derive(Debug)]
struct FileMetadata {
name: String,
size: u64,
permissions: FilePermissions,
}
// 自定义错误类型
#[derive(Debug)]
enum FileMetadataError {
IoError(io::Error),
PermissionError,
OtherError,
}
// 实现From<io::Error> for FileMetadataError
impl From<io::Error> for FileMetadataError {
fn from(error: io::Error) -> Self {
if error.kind() == io::ErrorKind::PermissionDenied {
FileMetadataError::PermissionError
} else {
FileMetadataError::IoError(error)
}
}
}
// 获取文件元数据的函数
fn get_file_metadata(path: &str) -> Result<FileMetadata, FileMetadataError> {
let metadata = std::fs::metadata(path)?;
let name = path.to_string();
let size = metadata.len();
let permissions = match metadata.mode() & 0o777 {
0o400 => FilePermissions::ReadOnly,
0o600 => FilePermissions::ReadWrite,
0o700 => FilePermissions::FullControl,
_ => FilePermissions::ReadOnly,
};
Ok(FileMetadata {
name,
size,
permissions,
})
}
fn main() {
let path = "/path/to/file";
match get_file_metadata(path) {
Ok(metadata) => println!("{:?}", metadata),
Err(error) => match error {
FileMetadataError::IoError(io_err) => eprintln!("I/O error: {}", io_err),
FileMetadataError::PermissionError => eprintln!("Permission denied"),
FileMetadataError::OtherError => eprintln!("Other error"),
},
}
}
优化策略
- 使用
From
trait:实现From<io::Error> for FileMetadataError
,这样可以方便地将io::Error
转换为FileMetadataError
,在get_file_metadata
函数中直接使用?
操作符,简化错误处理代码。
- 减少重复代码:通过统一错误转换逻辑,避免在多个地方重复处理相同类型的错误,使代码更简洁和易维护。例如在
from
方法中,根据io::Error
的具体类型决定转换为FileMetadataError
的哪种变体。