Rust 中,文件讀寫處理簡單而高效。代碼也很緊湊,容易閱讀。我們從讀取文件的字符串行、避免讀取寫入同一文件、使用內存映射隨機訪問文件這三個文件處理中的典型案例來了解一下。
文件處理場景大家都很熟悉,因此閑言少敘,直接看代碼。
讀取文件的字符串行
我們向文件寫入三行信息,然后使用 BufRead::lines 創建的迭代器 Lines 讀取文件,一次讀回一行。File 模塊實現了提供 BufReader 結構體的 Read trait。File::create 打開文件 File 進行寫入,File::open 則進行讀取。
use std::fs::File;use std::io::{Write, BufReader, BufRead, Error};fn main() -> ResultError> { let path = "lines.txt"; let mut output = File::create(path)?; write!(output, "Rust\n?\nFun")?; let input = File::open(path)?; let buffered = BufReader::new(input); for line in buffered.lines() { println!("{}", line?); } Ok(())}
文件處理中避免讀寫同一文件
對文件使用 same_file::Handle 結構體,可以測試文件句柄是否等同。在本實例中,將對要讀取和寫入的文件句柄進行相等性測試。
use same_file::Handle;use std::fs::File;use std::io::{BufRead, BufReader, Error, ErrorKind};use std::path::Path;fn main() -> Result { let path_to_read = Path::new("new.txt"); let stdout_handle = Handle::stdout()?; let handle = Handle::from_path(path_to_read)?; if stdout_handle == handle { return Err(Error::new( ErrorKind::Other, "You are reading and writing to the same file", )); } else { let file = File::open(&path_to_read)?; let file = BufReader::new(file); for (num, line) in file.lines().enumerate() { println!("{} : {}", num, line?.to_uppercase()); } } Ok(())}
使用內存映射隨機訪問文件
使用 memmap 創建文件的內存映射,并模擬文件的一些非序列讀取。使用內存映射意味著您僅需索引一個切片,而不是使用 seek 方法來導航整個文件。
map::map 函數假定內存映射后的文件沒有被另一個進程同時更改,否則會出現競態條件。
use memmap::Mmap;use std::fs::File;use std::io::{Write, Error};fn main() -> ResultError> { write!(File::create("content.txt")?, "My hovercraft is full of eels!")?; let file = File::open("content.txt")?; let map = unsafe { Mmap::map(&file)? }; let random_indexes = [0, 1, 2, 19, 22, 10, 11, 29]; assert_eq!(&map[3..13], b"hovercraft"); let random_bytes: Vec = random_indexes.iter() .map(|&idx| map[idx]) .collect(); assert_eq!(&random_bytes[..], b"My loaf!"); Ok(())}
以上實例代碼都是完整的、可獨立運行的程序,因此你可以直接復制它們到自己的項目中進行試驗。
如果希望從頭了解如何運行上述實例代碼,請參考《Rust 實踐指南》中關于本書-如何使用本書實例部分。也可以復制鏈接:http://budshome.com/rust-cookbook/about.html 點擊閱讀原文進行更詳細的學習。