用 Rust 讀寫檔案

Nilesh Katuwal 2023年1月30日
  1. 在 Rust 1.26 及更高版本中讀取檔案到字串
  2. 在 Rust 1.26 及更高版本中將檔案讀取為 Vec<u8>
  3. 在 Rust 1.26 及更高版本中用 Rust 編寫檔案
  4. 在 Rust 1.0 中讀取檔案到字串
  5. 在 Rust 1.0 中將檔案讀取為 Vec<u8>
  6. 在 Rust 中建立一個函式
用 Rust 讀寫檔案

我們將在本主題中學習如何使用各種技術在不同版本的 Rust 中讀取和寫入檔案。學習錯誤處理會更容易理解和處理程式中的錯誤。

Rust 1.26 及更高版本中,單行函式可用於讀取和寫入檔案。

在 Rust 1.26 及更高版本中讀取檔案到字串

use std::fs;

fn main() {
    let info = fs::read_to_string("/etc/hosts").expect("The file could not be read");
    println!("{}", info);
}

std::fs 模組包括操作本地檔案系統內容的基本技術。read_to_string() 函式開啟具有較少 imports 的檔案,不包括中間變數。

其工作機制與 File::open 相同。我們會將檔案-/etc/hosts 中的內容儲存到 info 中,然後列印出來。

輸出:

128.127.0.0.1   localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

在 Rust 1.26 及更高版本中將檔案讀取為 Vec<u8>

VecVector 的簡寫形式,u8 指的是 8 位無符號整數型別。下面的程式碼用於將檔案作為 Vec<u8> 讀取。

use std::fs;

fn main() {
    let info = fs::read("/etc/hosts").expect("The file could not be read");
    println!("{}", info.len());
}

輸出:

150

在 Rust 1.26 及更高版本中用 Rust 編寫檔案

現在,讓我們看一個使用 Rust 1.26 編寫檔案的示例。

use std::fs::File;
use std::io::{Write, BufReader, BufRead, Error};

fn main() -> Result<(), Error> {
    let path = "/home/user/words.txt";

    let mut output = File::create(path)?;
    write!(output, "Tick\n\nToe")?;

    let input = File::open(path)?;
    let buffered = BufReader::new(input);

    for words in buffered.lines() {
        println!("{}", words?);
    }

    Ok(())
}

在上面的程式碼中,File::create 開啟一個檔案用於寫入,File::open 用於讀取。BufRead 有一個內部緩衝區來讀取檔案,並且對於逐行讀取更有用。

緩衝區讀取器或寫入器使用緩衝區來減少 I/O 請求,並且訪問一次磁碟以讀取 256 位元組比訪問同一磁碟 256 次要實用得多。std::io 模組提供了多種有用的功能來進行輸入和輸出,例如 ReadWrite

輸出:

Tick

Toe

在 Rust 1.0 中讀取檔案到字串

這些方法比分配 StringVec 的單行函式更冗長。但是,它們更強大,因為分配的資料可以重用或新增到現有物件。

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

fn main() {
    let mut info = String::new();
    let mut f = File::open("/etc/hosts").expect("The file cannot be opened");
    f.read_to_string(&mut data).expect("The string cannot be read");
    println!("{}", info);
}

mut 關鍵字是指可變的,File::open 開啟路徑/etc/hosts 中的檔案。上面的程式碼指示將檔案讀取為字串,而 expect 用於錯誤處理。

輸出:

128.127.0.0.1   localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

在 Rust 1.0 中將檔案讀取為 Vec<u8>

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

fn main() {
    let mut info = Vec::new();
    let mut f = File::open("/etc/hosts").expect("The file cannot be opened");
    f.read_to_end(&mut info).expect("The information cannot be read");
    println!("{}", info.len());
}

read_to_end() 以大塊的形式複製資料。因此,傳輸可以自然地合併為更少的 I/O 操作。

輸出:

150

在 Rust 中建立一個函式

create 函式用於以只寫模式開啟檔案。如果檔案已經存在,則覆蓋之前的內容,並生成一個新的。

use std::fs::File;
use std::io::Write;
fn main() {
    let info = "This is a sentence that exists in file.";
    let mut f = File::create("words.txt")
        .expect("unable to create file");
    f.write_all(info.as_bytes()).expect("Could not write");
}

輸出:

然後我們使用 cat 命令從 words.txt 中讀取文字。

$ cat words.txt

輸出:

This is a sentence that exists in file.