Rust基础(读写文件)

Rust文件读写

文件读写之前先简单介绍一下rust的两个常见enum。

enum Option<T>{
  Some(T),
  None,
}

这里的Option是一个泛型enum,它可以接收任意类型T然后包装其为一个Option enum。举个例子,有时候我们读文件的时候,成功读取则返回”success”否则返回”None”。Rust是编译型语言,作为返回值的两个分支必须是相同的类型否则则无法通过编译。当然我们可以返回一个””空字符串,但不够优雅。enum结合泛型就能封装任意类型为特定的enum。这里的Option就是。其中Some(T)表示包含T的Option类型,None表示不包含T的Option类型。

enum Result<T, E> {
    Ok(T),
    Err(E),
}

文件读


fn file_to_str(filename: String) -> String {
    let mut file = fs::File::open(filename).expect("无法打开文件");
    let mut mesg = String::new();
    file.read_to_string(&mut mesg);
    mesg
}

上面的代码中读取filename中的文件为字符串,类似于python中的f.read()。fs::File::open(filename)返回的就是一个Result,这里成功打开结果就是File类型的file,否则爆出”无法打开文件”的错误。文件读取为向量:

fn file_to_vec(filename: String) -> std::io::Result<Vec<u8>> {
    let mut file = fs::File::open(filename).expect("无法打开文件");
    let mut buf = Vec::new();//创建一个空的向量
    file.read_to_end(&mut buf);//将读取的内容的数值写入向量
    return Ok(buf);//返回包装之后的Result
}

上述代码中,文件字符使用uint8编码,类似于python中的byte。直接打印输出则会输出数值。

fn file_to_vec_with_buffer(filename: String) -> std::io::Result<Vec<String>> {
    let mut file = fs::File::open(filename).expect("无法打开文件");
    let io_buffer = BufReader::new(file);
    io_buffer.lines().into_iter().collect()
}

使用BufReader读取文件行保存为Vec<String>,结果封装在Result中。完整代码:

use std::fs;
use std::io::BufRead;
use std::io::{BufReader, Read};
fn file_to_str(filename: &String) -> String {
    let mut file = fs::File::open(filename).expect("无法打开文件");
    let mut mesg = String::new();
    file.read_to_string(&mut mesg);
    mesg
}
fn file_to_vec(filename: &String) -> std::io::Result<Vec<u8>> {
    let mut file = fs::File::open(filename).expect("无法打开文件");
    let mut buf = Vec::new();
    file.read_to_end(&mut buf);
    return Ok(buf);
}
fn file_to_vec_with_buffer(filename: &String) -> std::io::Result<Vec<String>> {
    let mut file = fs::File::open(filename).expect("无法打开文件");
    let io_buffer = BufReader::new(file);
    io_buffer.lines().into_iter().collect()
}
fn main() {
    let filename = "/tmp/log".to_string();
    let msg = file_to_str(&filename);
    println!("line is :{:?}", msg);
}

文件写

fn write_msg_to_file(filename: &String, msg: &str) {
    let mut file = fs::File::create(filename).unwrap();
    write!(file, "{}", msg);
}

或者:


fn write_msg_to_file(filename: &String, msg: &str) {
    let mut file = fs::File::create(filename).unwrap();
    file.write(msg.as_bytes());
}

完整代码:

use std::fs;
use std::io::Write;

fn write_msg_to_file(filename: &String, msg: &str) {
    let mut file = fs::File::create(filename).unwrap();
    file.write(msg.as_bytes());
}
fn main() {
    let filename = "/tmp/log".to_string();
    let mesg = "hello world\n你好世界";
    write_msg_to_file(&filename, &mesg);
}

Result 常见API

  • is_ok(self)->bool:如果Result是Ok则返回true,否则返回false。
  • is_ok_and(self, f: impl FnOnce(T) -> bool) -> bool:如果Result是ok的话进一步判断。
  • is_err(&self) -> bool:如果是Err则返回true否则返回false。
  • is_err_and(self, f: impl FnOnce(E) -> bool) -> bool:如果是Err再使用函数判断。
  • ok(self) -> Option<T>:将Ok转换为Option
  • err(self) -> Option<E>:将Err转换为Option
  • as_ref(&self) -> Result<&T, &E>:转换 &Result<T, E> 为 Result<&T, &E>。
  • as_mut(&mut self) -> Result<&mut T, &mut E>:转换 Result<&T, &E> 为 &Result<T, E> 。
  • map<U, F>(self, op: F) -> Result<U, E>:映射Result<T, E> 为 Result<U, E>,此函数在Ok状态下执行映射函数。
  • map_or<U, F>(self, default: U, f: F) -> U:如果为Ok则执行映射函数否则返回默认值Default。
  • map_or_else<U, D, F>(self, default: D, f: F) -> U:如果是Ok则执行映射函数f,否则在Err上执行d。
  • map_err<F, O>(self, op: O) -> Result<T, F>:如果是Ok则直接返回本身,否则对Err使用映射函数。
  • inspect<F>(self, f: F) -> Result<T, E>:如果是Ok则以引用的形式调用函数。
  • inspect_err<F>(self, f: F) -> Result<T, E>:如果是Err则以引用的形式调用函数。
  • as_deref(&self) -> Result<&<T as Deref>::Target, &E>:转换Result<T, E> (或者 &Result<T, E>) 为 Result<&::Target, &E>。
  • as_deref_mut(&mut self) -> Result<&mut <T as Deref>::Target, &mut E>:转换Result<T, E> (或者 &mut Result<T, E>) 为 Result<&mut ::Target, &mut E>。
  • iter(&self) -> Iter<'_, T>:返回迭代器,如果为Ok则返回Result::Ok的值否则为None。
  • iter_mut(&mut self) -> IterMut<'_, T>:返回迭代器,如果为Ok则返回Result::Ok的值否则为None。其中返回值可以被修改。
  • expect(self, msg: &str) -> T:返回Ok包含的值,如果是Err则报错。
  • unwrap(self) -> T:如果为Ok则返回值本身否则将报错。
  • unwrap_or_default():如果为Ok则返回值否则返回默认值。
  • expect_err(self, msg: &str) -> E where T:Debug:返回Err的值,如果是Ok则报错。
  • unwrap_err(self)->E where T:Debug:返回Err包含的值。
  • into_ok(self) -> T where E:Into<!>:返回Ok包含的值,不报任何错误。
  • into_err(self)->E where T:Into<!>:返回Err包含的值,不报任何错误。
  • and<U>(self, res: Result<U, E>) -> Result<U, E>:如果是Ok则返回res否则返回self。
  • and_then<U, F>(self, op: F) -> Result<U, E> where F:FnOnce(T)->Result(U,E):如果是Ok则调用op否则返回对应的Err值。
  • or<F>(self, res: Result<T, F>) -> Result<T, F>:如果是Err则返回res否则返回对应的Ok
  • or_else<F, O>(self, op: O) -> Result<T, F> where O: FnOnce(E) -> Result<T, F>:如果结果为Err则调用op否则返回Ok本身。
  • unwrap_or(self, default: T) -> T:返回Ok的值否则提供默认值。
  • unwrap_or_else<F>(self, op: F) -> T where F: FnOnce(E) -> T:返回Ok的值或者返回使用闭包计算的值。
  • unwrap_unchecked(self) -> T(Unsafe):返回包含Ok的值,不检查是否为Err。调用此方法可能产生未定义的行为。
  • unwrap_err_unchecked(self) -> E(Unsafe):返回Err包含的值不检查是否为Ok。调用此方法可能产生未定义的行为。
  • copied(self) -> Result<T, E> where T:Copy:通过拷贝Ok的内容,映射Result<&T, E> 为Result<T, E>。
  • cloned(self) -> Result<T, E>:通过clone Ok的值映射Result<&T, E> 为 Result<T, E>。
  • transpose(self) -> Option<Result<T, E>>:transpose 一个Result为另一个Result。Ok(None)被映射为NoneOk(Some(_))Err(_)被映射为Some(Ok(_))Some(Err(_))
  • flatten(self) -> Result<T, E>:转换Result<Result<T, E>, E> 为 Result<T, E>。
  • from_iter<I>(iter: I) -> Result<V, E> where I: IntoIterator<Item = Result<A, E>>:将容器中的每个元素拿出来然后使用Ok包装,否则返回Err
  • into_iter(self) -> IntoIter<T>:如果值为Ok则返回包含值的迭代器。
  • product<I>(iter: I) -> Result<T, E>:如果为Ok则取出每一个元素累乘后包装,否则Err插入其中。
  • sum<I>(iter: I) -> Result<T, E> where I: Iterator<Item = Result<U, E>>,:一直获取其中的元素直到无法获取下一个元素或者其本身为Err为止,返回元素的和。
  • report(self) -> ExitCode:调用函数返回状态码。

   转载规则


《Rust基础(读写文件)》 bleedingfight 采用 知识共享署名 4.0 国际许可协议 进行许可。
 上一篇
Rust基础(字符串) Rust基础(字符串)
字符串rust String类似于C++中的std::string,本质上是一种容纳字符串的容器。但是多了更多的操作方法。字符串字面量是Rust中的常规字符串,它本身也有一些方法。 字符串切片字符串字面量常见的方法: len:获取字符串元
下一篇 
异构计算基础 异构计算基础
CUDA编程基础(C++特性)内存限定符 __device__: __shared__: __global__: __constant__:仅仅可以从host代码通过runtime函数赋值,不能从device侧赋值。__device__、_
2023-09-09
  目录