交互式地坚持现有文件名并打开它的习惯性 rust

2w3kk1z5  于 2022-11-24  发布在  其他
关注(0)|答案(1)|浏览(139)

我正在解析一个Evernote导出文件以提取一些数据。我想我应该在Rust中实现这个解析器,作为自学一些语言的一种方式。我想以交互方式获得包含导出的Evernote数据的文件名。我在网上找到了许多在Rust中打开文件的示例,但它们都在一个错误时死机。这不是我想做的。我想一直问下去,直到用户指定了一个可以打开阅读的文件。
我已经写了下面的代码。它看起来工作得很好,但我不能相信没有更简单,更惯用的解决方案,所以我想我会在这里问。
还有一点让我感到困扰的是,如果不编写自己的文本提取函数,你就无法从任何生成的错误中提取出人工优化的“消息”组件,但2018年有一个关于堆栈溢出的答案表明情况确实如此,如果2022年的答案是不同的,我很想知道。

// Set up a handle for stdin.
    let stdin = io::stdin();
    
    // Set up file pointer
    let mut input_file: File;
    
    // Open a user specified file name.
    let mut file_opened = false;
    while ! file_opened {
        
        let mut filename = String::new();
        print!("Enter the name of the Evernote export file you want to convert: ");
        io::stdout().flush().expect("Encountered an unexpected error: The input buffer would not flush.");
        stdin.read_line(&mut filename).expect("Error: unable to read the file name.");
        filename = filename.trim_end().to_string();
        
        let input_file_result = File::open(filename);
        if input_file_result.is_ok() {
            file_opened = true;
            input_file = input_file_result.unwrap();
        } else {
            println!("Could not open an Evernote export file with that name. The error reported was '{:?}'.", input_file_result.err().unwrap());
        }
        
    }
bihw5rsg

bihw5rsg1#

如果你的函数返回一个io::Result,你可以用?代替.expects,并转发错误。main也可以返回一个Result,如果你提前返回?,它会显示Err的内容的错误信息。

use std::{io::{self, Write}, fs::File};
fn main() -> io::Result<()> {
    // Set up a handle for stdin.
    let stdin = io::stdin();

    // Like @BlackBeans noted declaring outside and .clear() inside the loop is more eficcient.
    let mut filename = String::new();
    let input_file = loop {
        print!("Enter the name of the Evernote export file you want to convert: ");
        io::stdout().flush()?;
        stdin.read_line(&mut filename)?;

        match File::open(filename.trim_end()) {
            Ok(file) => break file,
            Err(e) => println!("Could not open an Evernote export file with that name. The error reported was '{e}'."),
        }
        filename.clear()
    };
    // do something with input_file
    Ok(())
}

相关问题