从std::io获取正确结果消息的惯用方法



我继续尝试Rust,有一个问题。我想从std::io有有用的消息,例如,当我试图打开文件时,我想在Err(err)的情况下得到<file_name>,但它不存在,例如:

fn read_to_string(file_name: &str) -> std::io::Result<String> {
let data = fs::read_to_string(file_name);
// let data = Ok(fs::read_to_string(file_name).expect(("Can not read file ".to_string() + file_name + "n").as_str()));
return data;
}

返回信息为:

[src/main.rs:26] res = Os {
code: 2,
kind: NotFound,
message: "No such file or directory",
}

没有任何<file_name>-这是如此奇怪,我怀疑我做错了什么。<file_name>是我最想要的数据

那么在Rust中获得<file_name>

输出的正确(或惯用)方式是什么呢?注1:是的,有日志记录,但它并不总是可能的-假设您从某个点遍历file_system,或者如果可能的话-您应该编写解析器以获得足够的信息。

注2:注释代码(与expect(...)函数)-可以给我需要的信息,这是在这种情况下最令人不安的事情。

有一些关于可能为内置IO操作添加路径的讨论,但现在您可以只将错误映射为包含文件名的消息:

fn read_to_string(file_name: &str) -> std::io::Result<String> {
fs::read_to_string(file_name).map_err(|e| {
std::io::Error::new(
e.kind(),
format!("Error while reading file {}: {}", file_name, e),
)
})
}

如果您可以使用外部板条箱,anyhow允许您将任意信息附加到任何错误,并保持完整的跟踪完整的错误堆栈:

use anyhow::{Context, Result};
use std::fs;
fn read_file (name: &str) -> Result<String> {
Ok (fs::read_to_string (name)
.with_context (|| format!("Could not read file {name}"))?)
}
fn main() -> Result<()> {
let contents = read_file ("unknown_file.txt")
.context ("Could not get file contents")?;
println!("File contents: {contents}");
Ok(())
}

游乐场

打印:

Error: Could not get file contents
Caused by:
0: Could not read file unknown_file.txt
1: No such file or directory (os error 2)

最新更新