การอ่านไฟล์ (Reading a File)
คราวนี้เราจะเพิ่มฟังก์ชันการทำงานเพื่ออ่านไฟล์ที่ระบุในอาร์กิวเมนต์ file_path ขั้นแรก เราต้องมีไฟล์ตัวอย่างเพื่อใช้นำมาทดสอบ: เราจะใช้ไฟล์ที่มีข้อความสั้นๆ หลายบรรทัดพร้อมคำที่ซ้ำกันบางคำ Listing 12-3 มีบทกวีของ Emily Dickinson ซึ่งจะเหมาะมากสำหรับใช้ทดสอบ! ให้สร้างไฟล์ชื่อ poem.txt ไว้ที่ระดับบนสุด (root level) ของโปรเจกต์ของคุณ และใส่บทกวี “I’m Nobody! Who are you?” ลงไป
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!
เมื่อใส่ข้อความเรียบร้อยแล้ว ให้แก้ไข src/main.rs และเพิ่มโค้ดสำหรับอ่านไฟล์ ดังแสดงใน Listing 12-4
use std::env;
use std::fs;
fn main() {
// --snip--
let args: Vec<String> = env::args().collect();
let query = &args[1];
let file_path = &args[2];
println!("Searching for {query}");
println!("In file {file_path}");
let contents = fs::read_to_string(file_path)
.expect("Should have been able to read the file");
println!("With text:\n{contents}");
}
ขั้นแรก เรานำส่วนที่เกี่ยวข้องของไลบรารีมาตรฐานเข้ามาด้วยคำสั่ง use: เราจำเป็นต้องใช้ std::fs เพื่อจัดการกับไฟล์
ใน main คำสั่งใหม่ fs::read_to_string จะรับค่า file_path เปิดไฟล์นั้น และคืนค่าเป็นประเภท std::io::Result<String> ซึ่งบรรจุเนื้อหาของไฟล์อยู่ภายใน
หลังจากนั้น เราเพิ่มคำสั่ง println! ชั่วคราวอีกครั้งเพื่อพิมพ์ค่าของ contents หลังจากอ่านไฟล์แล้ว เพื่อที่เราจะได้ตรวจสอบว่าโปรแกรมทำงานได้ถูกต้องในตอนนี้
ลองรันโค้ดนี้โดยใช้สตริงใดก็ได้เป็นอาร์กิวเมนต์แรกของบรรทัดคำสั่ง (เนื่องจากเรายังไม่ได้ปรับใช้ส่วนการค้นหา) และใช้ไฟล์ poem.txt เป็นอาร์กิวเมนต์ตัวที่สอง:
$ cargo run -- the poem.txt
Compiling minigrep v0.1.0 (file:///projects/minigrep)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.0s
Running `target/debug/minigrep the poem.txt`
Searching for the
In file poem.txt
With text:
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 มีหน้าที่รับผิดชอบหลายอย่าง: โดยทั่วไปแล้ว ฟังก์ชันจะชัดเจนและบำรุงรักษาได้ง่ายกว่า หากแต่ละฟังก์ชันรับผิดชอบเพียงแนวคิดเดียวเท่านั้น ปัญหาใหญ่อีกประการหนึ่งคือเรายังไม่ได้จัดการกับข้อผิดพลาดดีเท่าที่ควร โปรแกรมยังคงมีขนาดเล็ก ข้อบกพร่องเหล่านี้จึงยังไม่เป็นปัญหาใหญ่ แต่เมื่อโปรแกรมขยายใหญ่ขึ้น การแก้ไขข้อบกพร่องเหล่านี้อย่างเป็นระเบียบจะทำได้ยากขึ้น ถือเป็นแนวทางปฏิบัติที่ดีที่จะเริ่มทำการรีแฟกเตอร์ (refactoring) ตั้งแต่เนิ่นๆ ในระหว่างการพัฒนาโปรแกรม เพราะการรีแฟกเตอร์โค้ดจำนวนน้อยนั้นทำได้ง่ายกว่ามาก เราจะทำสิ่งนั้นในหัวข้อถัดไป