خواندن یک فایل

اکنون قابلیت خواندن فایل مشخص‌شده در آرگومان file_path را اضافه می‌کنیم. ابتدا به یک فایل نمونه برای تست نیاز داریم: از یک فایل با مقدار کمی متن در چندین خط که برخی کلمات در آن تکرار شده‌اند استفاده می‌کنیم. لیست ۱۲-۳ شامل شعری از امیلی دیکینسون است که به خوبی برای این منظور مناسب است! یک فایل به نام poem.txt در سطح اصلی پروژه خود ایجاد کنید و شعر “I’m Nobody! Who are you?” را وارد کنید.

Filename: 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!
Listing 12-3: شعری از امیلی دیکینسون که مورد تست مناسبی است.

با متن در جای خود، فایل src/main.rs را ویرایش کرده و کدی برای خواندن فایل اضافه کنید، همانطور که در لیست ۱۲-۴ نشان داده شده است.

Filename: src/main.rs
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}");
}
Listing 12-4: خواندن محتوای فایل مشخص‌شده توسط آرگومان دوم

ابتدا بخشی مرتبط از کتابخانه استاندارد را با یک دستور 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 چندین مسئولیت دارد: به طور کلی، توابع واضح‌تر و آسان‌تر برای نگهداری هستند اگر هر تابع فقط مسئول یک ایده باشد. مشکل دیگر این است که ما خطاها را به خوبی مدیریت نمی‌کنیم. برنامه هنوز کوچک است، بنابراین این مشکلات مشکل بزرگی نیستند، اما با رشد برنامه، رفع آن‌ها به صورت تمیز سخت‌تر خواهد شد. بهتر است که زودتر در فرایند توسعه برنامه شروع به بازسازی کنیم، زیرا بازسازی کدهای کمتر بسیار آسان‌تر است. در مرحله بعد این کار را انجام خواهیم داد.