Rust 中的文件操作示例詳解
文件路徑
想要打開或者創(chuàng)建一個文件,首先要指定文件的路徑。
Rust 中的路徑操作是跨平臺的,std::path 模塊提供的了兩個用于描述路徑的類型:
PathBuf– 具有所有權并且可被修改,類似于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();
// 返回文件名(不包含文件擴展名)
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);
// 根據字符串切片創(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 模塊提供了一系列文件系統操作的功能。
目錄創(chuàng)建和刪除
創(chuàng)建目錄的函數:
create_dir<P: AsRef<Path>>(path: P) -> Result<()>– 創(chuàng)建一個空目錄,若指定路徑不存在則會返回錯誤create_dir_all<P: AsRef<Path>>(path: P) -> Result<()>– 級聯創(chuàng)建目錄。
示例:
use std::fs;
// 由于字符串切片實現了 `AsRef<Path>` Trait,因此函數中的參數可以直接使用字符串字面量
fn main() -> std::io::Result<()> {
// 創(chuàng)建一個空目錄
fs::create_dir("./empty")?;
// 創(chuàng)建一個目錄,若其上級目錄不存在,則一同創(chuàng)建
fs::create_dir_all("./some/dir")?;
Ok(())
}
刪除目錄的函數:
remove_dir<P: AsRef<Path>>(path: P) -> Result<()>– 刪除指定空目錄。remove_dir_all<P: AsRef<Path>>(path: P) -> Result<()>– 刪除指定目錄及其目錄下的內容。
示例:
use std::fs;
fn main() -> std::io::Result<()> {
// 刪除一個空目錄
fs::remove_dir("./empty")?;
// 刪除指定目錄及其目錄下的內容,但不會刪除其上級目錄
fs::remove_dir_all("./some/dir")?;
Ok(())
}
文件創(chuàng)建和刪除
Rust 使用 std::fs::File 結構體與文件系統中的文件相關聯,通過 std::fs::File 實例可以對文件進行讀取和寫入。
文件創(chuàng)建和刪除的函數:
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<()> {
// 以只寫模式打開指定文件,若文件存在則清空文件內容,若文件不存在則新建一個
let mut f = File::create("foo.txt")?;
// 刪除文件
fs::remove_file("foo.txt")?;
Ok(())
}
文件讀取和寫入
std::fs::File 本身實現了 Read 和 Write Trait,所以文件的讀寫非常簡單。
文件打開
在讀寫文件之前,首先應該得到一個 File 類型實例。除了可以在創(chuàng)建文件時獲取 File 實例,還可以使用 File 的 open 函數:
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 函數獲取的 File 實例是只讀或者只寫的,如果想要控制更多的讀寫選項,則需要使用 std::fs::OpenOptions。它是一個 Builder,create 和 open 函數的底層也是這個 Builder。
使用 std::fs::OpenOptions 時,首先調用 OpenOptions::new,然后通過鏈式調用來設置讀寫選項,最后調用 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) // 追加內容
.open("foo.txt")?;
let _file = OpenOptions::new()
.write(true)
.truncate(true) // 清空文件
.open("foo.txt");
Ok(())
}
文件讀取
讀取文件主要用的是 std::io::Read Trait 中的函數。比如:
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();
// 讀取文件所有內容并轉為字符字符串,若文件非 UTF-8 格式,則會報錯
f.read_to_string(&mut buffer)?;
println!("The string: {}", buffer);
Ok(())
}
另外,File 類型還實現了 std::io::Seek Trait,Seek 主要提供了一個 seek 函數,可以控制文件讀取和寫入的起始位置。
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")?;
// 將游標前移 10 個字節(jié)(游標的默認位置是 0)
f.seek(SeekFrom::Start(10))?;
// 將前 10 個字節(jié)之后的內容讀取到 Buf 中
let mut buffer = String::new();
f.read_to_string(&mut buffer)?;
println!("The string: {}", buffer);
Ok(())
}
除了可以設置文件讀取的起點,還可以限制文件讀取的長度。std::io::Read 提供了 take 函數來限制文件讀取的長度。
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 中的函數。比如:
fn write(&mut self, buf: &[u8]) -> Result<usize>– 嘗試將 Buf 中的全部內容寫入文件,有可能不成功。fn flush(&mut self) -> Result<()>fn write_all(&mut self, buf: &[u8]) -> Result<()>– 持續(xù)調用write,將 Buf 中的所有內容都寫入文件。
示例:
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(())
}
相關資料
到此這篇關于Rust 中的文件操作的文章就介紹到這了,更多相關Rust 文件操作內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
關于使用rust調用c++靜態(tài)庫并編譯nodejs包的問題
這篇文章主要介紹了使用rust調用c++靜態(tài)庫并編譯nodejs包的問題,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-08-08

