讀取檔案
現在我們要加上能夠讀取 filename
中命令列引數指定的檔案功能。首先我們需要有個檔案範本能讓我們測試,要確保 minigrep
執行無誤的最佳檔案範本就是文字文件,其中由數行重複的單字組成少量文字。範例 12-3 Emily Dickinson 的詩就是不錯的選擇!在專案根目錄建立一個檔案叫做 poem.txt,然後輸入此詩 「I’m Nobody! Who are you?」
檔案名稱:poem.txt
I’m nobody! Who are you?
Are you nobody, too?
Then there’s a pair of us - don’t tell!
They’d banish us, you know.
How dreary to be somebody!
How public, like a frog
To tell your name the livelong day
To an admiring bog!
範例 12-3:以 Emily Dickinson 的詩作為絕佳測試範本
有了這些文字,接著修改 src/main.rs 來加上讀取檔案的程式碼,如範例 12-4 所示。
檔案名稱:src/main.rs
use std::env; use std::fs; fn main() { // --省略-- let args: Vec<String> = env::args().collect(); let query = &args[1]; let filename = &args[2]; println!("搜尋 {}", query); println!("目標檔案為 {}", filename); let contents = fs::read_to_string(filename) .expect("讀取檔案時發生了錯誤"); println!("文字內容:\n{}", contents); }
範例 12-4:讀取第二個引數指定的檔案內容
首先,我們加上另一個 use
陳述式來將標準函式庫中的另一個相關部分引入:我們需要 std::fs
來處理檔案。
在 main
中,我們加上新的陳述式:fs::read_to_string
會接收 filename
、開啟該檔案並回傳檔案內容的 Result<String>
。
在陳述式之後,我們再次加上暫時的 println!
陳述式來在讀取檔案之後,顯示 contents
的數值,讓我們能檢查程式目前運作無誤。
讓我們用任何字串作為第一個命令列引數(因為我們還沒實作搜尋的部分)並與 poem.txt 檔案作為第二個引數來執行此程式碼:
$ cargo run the poem.txt
Compiling minigrep v0.1.0 (file:///projects/minigrep)
Finished dev [unoptimized + debuginfo] target(s) in 0.0s
Running `target/debug/minigrep the poem.txt`
搜尋 the
目標檔案為 poem.txt
文字內容:
I’m nobody! Who are you?
Are you nobody, too?
Then there’s a pair of us - don’t tell!
They’d banish us, you know.
How dreary to be somebody!
How public, like a frog
To tell your name the livelong day
To an admiring bog!
很好!程式碼有讀取並印出檔案內容。但此程式碼有些缺陷。main
函式負責太多事情了,通常如果每個函式都只負責一件事的話,函式才能清楚直白且易於維護。另一個問題是我們盡可能地處理錯誤。由於程式還很小,此缺陷不算什麼大問題,但隨著程式增長時,這會越來越難清楚地修正。在開發程式時盡早重構是很好的做法,因為重構少量的程式碼會比較簡單。接下來就讓我們開始吧。
- translators: [Ngô͘ Io̍k-ūi [email protected]]
- commit: e5ed971
- updated: 2020-10-02