Rust 中的文件操作示例詳解
文件路徑
想要打開或者創(chuàng)建一個文件,首先要指定文件的路徑。
Rust 中的路徑操作是跨平臺的,std::path
模塊提供的了兩個用于描述路徑的類型:
PathBuf
– 具有所有權(quán)并且可被修改,類似于String
。Path
– 路徑切片,類似于str
。
示例:
use std::path::Path; use std::path::PathBuf; fn main() { // 直接將一個字符串切片包裝成一個路徑切片 let path = Path::new("./foo/bar.txt"); // 返回上級路徑,若無上級路徑則返回 `None` let parent = path.parent().unwrap(); // 返回文件名(不包含文件擴(kuò)展名) let file_stem = path.file_stem().unwrap(); println!( "path: {:?}, parent: {:?}, file_stem: {:?}", path, parent, file_stem ); // 創(chuàng)建一個空的 `PathBuf` let mut empty_path = PathBuf::new(); println!("empty_path: {:?}", empty_path); // 根據(jù)字符串切片創(chuàng)建 `PathBuf` let path = PathBuf::from(r"C:\windows\system32.dll"); // 添加路徑 empty_path.push(r"C:\"); println!("empty_path: {:?}, path: {:?}", empty_path, path); }
文件創(chuàng)建和刪除
Rust 的 std::fs
模塊提供了一系列文件系統(tǒng)操作的功能。
目錄創(chuàng)建和刪除
創(chuàng)建目錄的函數(shù):
create_dir<P: AsRef<Path>>(path: P) -> Result<()>
– 創(chuàng)建一個空目錄,若指定路徑不存在則會返回錯誤create_dir_all<P: AsRef<Path>>(path: P) -> Result<()>
– 級聯(lián)創(chuàng)建目錄。
示例:
use std::fs; // 由于字符串切片實(shí)現(xiàn)了 `AsRef<Path>` Trait,因此函數(shù)中的參數(shù)可以直接使用字符串字面量 fn main() -> std::io::Result<()> { // 創(chuàng)建一個空目錄 fs::create_dir("./empty")?; // 創(chuàng)建一個目錄,若其上級目錄不存在,則一同創(chuàng)建 fs::create_dir_all("./some/dir")?; Ok(()) }
刪除目錄的函數(shù):
remove_dir<P: AsRef<Path>>(path: P) -> Result<()>
– 刪除指定空目錄。remove_dir_all<P: AsRef<Path>>(path: P) -> Result<()>
– 刪除指定目錄及其目錄下的內(nèi)容。
示例:
use std::fs; fn main() -> std::io::Result<()> { // 刪除一個空目錄 fs::remove_dir("./empty")?; // 刪除指定目錄及其目錄下的內(nèi)容,但不會刪除其上級目錄 fs::remove_dir_all("./some/dir")?; Ok(()) }
文件創(chuàng)建和刪除
Rust 使用 std::fs::File
結(jié)構(gòu)體與文件系統(tǒng)中的文件相關(guān)聯(lián),通過 std::fs::File
實(shí)例可以對文件進(jìn)行讀取和寫入。
文件創(chuàng)建和刪除的函數(shù):
create<P: AsRef<Path>>(path: P) -> Result<File>
std::fs::remove_file<P: AsRef<Path>>(path: P) -> Result<()>
示例:
use std::fs; use std::fs::File; fn main() -> std::io::Result<()> { // 以只寫模式打開指定文件,若文件存在則清空文件內(nèi)容,若文件不存在則新建一個 let mut f = File::create("foo.txt")?; // 刪除文件 fs::remove_file("foo.txt")?; Ok(()) }
文件讀取和寫入
std::fs::File
本身實(shí)現(xiàn)了 Read
和 Write
Trait,所以文件的讀寫非常簡單。
文件打開
在讀寫文件之前,首先應(yīng)該得到一個 File
類型實(shí)例。除了可以在創(chuàng)建文件時獲取 File
實(shí)例,還可以使用 File
的 open
函數(shù):
open<P: AsRef<Path>>(path: P) -> Result<File>
示例:
use std::fs::File; fn main() -> std::io::Result<()> { // 以只讀模式打開指定文件,若文件不存在則返回錯誤 let _file = File::open("foo.txt")?; Ok(()) }
使用 create
和 open
函數(shù)獲取的 File 實(shí)例是只讀或者只寫的,如果想要控制更多的讀寫選項(xiàng),則需要使用 std::fs::OpenOptions
。它是一個 Builder,create
和 open
函數(shù)的底層也是這個 Builder。
使用 std::fs::OpenOptions
時,首先調(diào)用 OpenOptions::new
,然后通過鏈?zhǔn)秸{(diào)用來設(shè)置讀寫選項(xiàng),最后調(diào)用 OpenOptions::open
打開指定的文件。
示例:
use std::fs::OpenOptions; fn main() -> std::io::Result<()> { let _file = OpenOptions::new() .read(true) .write(true) .create(true) // 新建,若文件存在則打開這個文件 .open("foo.txt")?; let _file = OpenOptions::new() .append(true) // 追加內(nèi)容 .open("foo.txt")?; let _file = OpenOptions::new() .write(true) .truncate(true) // 清空文件 .open("foo.txt"); Ok(()) }
文件讀取
讀取文件主要用的是 std::io::Read
Trait 中的函數(shù)。比如:
read(&mut self, buf: &mut [u8]) -> Result<usize>
read_to_string(&mut self, buf: &mut String) -> Result<usize>
示例:
use std::fs::File; use std::io; // `prelude` 模塊包含通常使用的 IO Trait: `BufRead`, `Read`, `Write`, `Seek` use std::io::prelude::*; fn main() -> io::Result<()> { let mut f = File::open("foo.txt")?; let mut buffer = [0; 10]; // 讀取文件中的前10個字節(jié) let n = f.read(&mut buffer[..])?; println!("The bytes: {:?}", &buffer[..n]); // 接著讀取10個字節(jié) let n = f.read(&mut buffer[..])?; println!("The bytes: {:?}", &buffer[..n]); let mut f = File::open("foo.txt")?; let mut buffer = String::new(); // 讀取文件所有內(nèi)容并轉(zhuǎn)為字符字符串,若文件非 UTF-8 格式,則會報(bào)錯 f.read_to_string(&mut buffer)?; println!("The string: {}", buffer); Ok(()) }
另外,File
類型還實(shí)現(xiàn)了 std::io::Seek
Trait,Seek
主要提供了一個 seek
函數(shù),可以控制文件讀取和寫入的起始位置。
seek(&mut self, pos: SeekFrom) -> Result<u64>
示例:
use std::fs::File; use std::io; use std::io::prelude::*; use std::io::SeekFrom; fn main() -> io::Result<()> { let mut f = File::open("foo.txt")?; // 將游標(biāo)前移 10 個字節(jié)(游標(biāo)的默認(rèn)位置是 0) f.seek(SeekFrom::Start(10))?; // 將前 10 個字節(jié)之后的內(nèi)容讀取到 Buf 中 let mut buffer = String::new(); f.read_to_string(&mut buffer)?; println!("The string: {}", buffer); Ok(()) }
除了可以設(shè)置文件讀取的起點(diǎn),還可以限制文件讀取的長度。std::io::Read
提供了 take
函數(shù)來限制文件讀取的長度。
take(self, limit: u64) -> Take<Self>
示例:
use std::fs::File; use std::io; use std::io::prelude::\*; fn main() -> io::Result<()> { let f = File::open("foo.txt")?; let mut buffer = [0; 10]; // 限制讀取長度最多為 5 字節(jié) let mut handle = f.take(5); handle.read(&mut buffer)?; println!("buffer: {:?}", buffer); Ok(()) }
文件寫入
讀取文件主要用的是 std::io::Write
Trait 中的函數(shù)。比如:
fn write(&mut self, buf: &[u8]) -> Result<usize>
– 嘗試將 Buf 中的全部內(nèi)容寫入文件,有可能不成功。fn flush(&mut self) -> Result<()>
fn write_all(&mut self, buf: &[u8]) -> Result<()>
– 持續(xù)調(diào)用write
,將 Buf 中的所有內(nèi)容都寫入文件。
示例:
use std::fs::File; use std::io::prelude::*; fn main() -> std::io::Result<()> { let mut buffer = File::create("foo.txt")?; buffer.write(b"some bytes")?; buffer.write_all(b"more bytes")?; buffer.flush()?; Ok(()) }
相關(guān)資料
到此這篇關(guān)于Rust 中的文件操作的文章就介紹到這了,更多相關(guān)Rust 文件操作內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
rust解決嵌套——Option類型的map和and_then方法的使用
這篇文章主要介紹了rust解決嵌套——Option類型的map和and_then方法,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-02-02Rust個人學(xué)習(xí)小結(jié)之Rust的循環(huán)
這篇文章主要介紹了Rust個人學(xué)習(xí)小結(jié)之Rust的循環(huán),今天主要了解了Rust語言的3種循環(huán)方法:?loop、while、for,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-01-01Rust使用kind進(jìn)行異常處理(錯誤的分類與傳遞)
Rust?有一套獨(dú)特的處理異常情況的機(jī)制,它并不像其它語言中的?try?機(jī)制那樣簡單,這篇文章主要介紹了Rust指南錯誤的分類與傳遞以及使用kind進(jìn)行異常處理,需要的朋友可以參考下2022-09-09