2016-11-23 7 views
-2

私は、ファイルを読み取り、データを解析しています:Read :: read_to_endメソッドからエラーを処理する方法は?

fn main() { 
    parse_torrentfile("ubuntu-16.04.1-server-amd64.torrent"); 
} 

fn parse_file(filename: &'static str) { 
    let mut f = File::open(&Path::new(filename)).unwrap(); 
    let mut v: Vec<u8> = Vec::new(); 
    let file_content = f.read_to_end(&mut v); 
    println!("{:?}", file_content); 
} 

ubuntu-16.04.1-server-amd64.torrentが存在する場合、これはうまく動作しますが、それが存在しない場合、このエラーが発生します。

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error { repr: Os { code: 2, message: "No such file or directory" } }' 

どのようにすることができますが「存在しないファイル」または「プロセスファイルの解析」を印刷しますか?

+1

'の代わりに' .unwrap() 'の.expect( "ファイルが存在しない" という。)'試してみてください。 – ljedrz

+0

@ljedrz Thxしかし、 'thread 'main' panicked at 'ファイルが存在しません:エラー{repr:Os {code:2、message:" No such file or directory "}}'、../src/ libcore/result.rs:799'、 'ファイルは存在しません 'というのは印刷できません。 – kai

+0

[* Rustプログラミング言語*エラー処理に関する章](https://doc.rust-lang.org/stable/book/error-handling.html)を読んでください。このエラーに特別なことは何もありません。 – Shepmaster

答えて

1

あなたはResultのマッチングの代わりに、unwrap()またはexpect()を呼び出すべきです。エラーが発生したら、それを印刷するか、異なるエラーを別々に処理したい場合は​​を見てください。

use std::fs::File; 
use std::path::Path; 
use std::io::Read; 

fn main() { 
    parse_file("doesnt_exist.txt"); 
} 

fn parse_file(filename: &'static str) { 
    let mut f = match File::open(&Path::new(filename)) { 
     Ok(f) => f, 
     Err(e) => { 
      use std::io::ErrorKind::*; 
      println!("Got error: {}", e); 
      match e.kind() { 
       NotFound => { 
        println!("File not found"); 
       } 
       k => { 
        println!("Error: {:?}", k); 
       } 
      } 
      return; 
     } 
    }; 
    let mut v: Vec<u8> = Vec::new(); 
    let file_content = f.read_to_end(&mut v); 

    println!("{:?}", file_content); 
} 

Playground

+0

'v'の型を指定する必要はありません。 – Shepmaster

+0

いいえ、明示的な問題は表示されません(それは質問から来たものです)。 –

+0

答えは** OPだけではないことを忘れないでください。彼らは*このQ&A *を見つけるすべての人のためのものです。だからこそ、私は自分の答えをできるだけ慣用的なものにしようと努力しています。 – Shepmaster

1

おそらく最も慣用的なアプローチは、結果をparse_fileの外側に広げて、mainにエラーを出力することでしょう。

use std::fs::File; 
use std::io::{Read, Error as IoError}; 
use std::path::Path; 

fn main() { 
    match parse_file("ubuntu-16.04.1-server-amd64.torrent") { 
     Err(e) => println!("{}", e), 
     _ => {} 
    } 
} 

fn parse_file(filename: &'static str) -> Result<(), IoError> { 
    let mut f = File::open(&Path::new(filename))?; 
    let mut v: Vec<u8> = Vec::new(); 
    let file_content = f.read_to_end(&mut v); 
    println!("{:?}", file_content); 

    Ok(()) 
} 

あなたは1行でエラーを印刷したいし、それを伝播する場合は、あなたの代わりにこのような何かを行うことができます:

fn main() { 
    parse_file("ubuntu-16.04.1-server-amd64.torrent"); 
} 

fn parse_file(filename: &'static str) -> Result<(), IoError> { 
    let mut f = File::open(&Path::new(filename)).map_err(|e| { 
      println!("{}", e); 
      e 
     })?; 

    let mut v: Vec<u8> = Vec::new(); 
    let file_content = f.read_to_end(&mut v); 
    println!("{:?}", file_content); 

    Ok(()) 
} 
+0

この答えには、非イディオム的な錆がたくさんあります。あなたが1つのブランチだけを気にしているなら、 'match'は 'if let'でなければなりません。 'v'の型を指定する必要はありません。 'map'と' map_err'は値を出力するような副作用に使うべきではありません。 – Shepmaster

+0

@Shepmaster私が慣用句を言ったとき、私はエラーを伝播することについて話していただけで、残りのコードはOPからほとんど変わっていませんでした。それから、OPがオンライナーを探して仕事を終えているように見えたので、私は第2の解決策を提案しました(これは少し醜いです)。 – eulerdisk

+0

答えは** OPだけではありません**。彼らは*このQ&A *を見つけるすべての人のためのものです。だからこそ、私は自分の答えをできるだけ慣用的なものにしようと努力しています。 – Shepmaster

関連する問題