Day 3:非同步 I/O 與檔案操作

學習目標

  • 用 tokio 的非同步檔案 API
  • 讀寫檔案使用 AsyncReadExt / AsyncWriteExt
  • 理解 async I/O 不會 block thread

今日重點

非同步檔案操作

use tokio::fs::File;
use tokio::io::{self, AsyncReadExt, AsyncWriteExt};

#[tokio::main]
async fn main() -> io::Result<()> {
    // 寫檔
    let mut file = File::create("hello.txt").await?;
    file.write_all(b"Hello, world!").await?;
    file.flush().await?;

    // 讀檔
    let mut contents = String::new();
    let mut file = File::open("hello.txt").await?;
    file.read_to_string(&mut contents).await?;
    println!("Contents: {}", contents);

    Ok(())
}

用 std::fs 改 tokio::fs

  • std::fs::read_to_stringtokio::fs::read_to_string(async)
  • std::io::Read trait → tokio::io::AsyncReadExt
  • std::io::Write trait → tokio::io::AsyncWriteExt

為什麼非同步?

傳統 blocking I/O 會卡住執行緒。async I/O 在等待硬碟/網路時釋放執行緒,讓同一個執行緒能同時服務非常多 I/O 任務。

練習

use tokio::fs;
use tokio::io::AsyncWriteExt;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 1. 用 tokio::fs 建立 data.txt 寫入多行
    let mut file = fs::File::create("data.txt").await?;
    file.write_all(b"line1\nline2\nline3\n").await?;

    // 2. 讀回並印出每一行
    let content = fs::read_to_string("data.txt").await?;
    for line in content.lines() { println!("{}", line); }
    Ok(())
}

自我檢查

  • 會用 tokio::fs 非同步讀寫檔
  • 知道 AsyncReadExt / AsyncWriteExt
  • 使用 ? 處理非同步錯誤
  • 理解 async I/O 的效率

深入連結

  • tokio 官方文件(File I/O)