@[TOC

文件读写

Rust的文件读写功能被封装在标准库的fs中,考虑到读取文件的前提是有一个文件,所以先来学习文件写入功能,示例如下

use std::fs;
fs::write("test.txt", "hello world").unwrap();

【write】函数非常简单,唯二的参数就是路径和内容,路径可以是字符串,也可以是Path类型;内容可以是字符串,也可以是字节数组。其返回值是一个Result类型,所以执行完毕之后需要进行处理,否则会被警告,unwrap的作用是将其转化为普通类型。

编译运行之后,会在同级目录下创建一个test.txt文件,内容为hello world。接下来通过fs中的函数进行读取。fs中提供了文本读取函数read_to_string与二进制读取函数read,后者回将读取到的内容识别为8位无符号整型的数组。示例如下

let txt:String = fs::read_to_string("test.txt").unwrap();
txt     //"hello world"

let vec:Vec<u8> = fs::read("test.txt").unwrap();
vec

其中,txt为hello world,vec为[104,101,108,108,111,32,119,111,114,108,100][104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100][104,101,108,108,111,32,119,111,114,108,100]

File

前面介绍的三个读写函数,功能比较单一,一个更加灵活的文件交互方案是用OpenOptions,这个结构体有点像其他编程语言中的open函数,可以指定创建的文件是否可以读写,示例如下

use std::io::{Write, Read, Seek, SeekFrom};

let mut file: fs::File = fs::OpenOptions::new(
    ).write(true
    ).read(true
    ).create(true
    ).truncate(false
    ).open("test.txt"
    ).expect("Failed to open file");

file.write_all(b"Hello, Rust!").unwrap();
file.seek(SeekFrom::Start(0))?;
let mut contents:String = String::new();
file.read_to_string(&mut contents)?;
contents    //"Hello, Rust!"

其中,【write】设为true表示可读;【create】设为true表示如果文件不存在则创建;【truncate】若设为true,则清空文件内容。最后打开test.txt。由于上述代码是写在evxcr中,所以在换行的时候把括号拆开了。

【write_all】是Write中为File封装的trait,所以尽管代码中国没有出现类似Write::xxx的字样,但还是要use一下,Read同理。

【seek】用于移动文件指针。由于刚刚在写操作的时候,文件指针已经在文件末尾,因此通过seek让其重返零点,从而在后面用read读取的时候,能够得到完整的内容。

追加模式

其实在上述代码中,只需在打开文件之后,先把文件指针移动到末尾,就可以开启追加模式。如果不想麻烦,也可以用append(true)。需要注意的是,append和truncate冲突,因为要是把truncate设为true的话,打开文件后内容被清空,就算是追加,也和新建一个没什么区别了。下面是追加文件内容的测试。

let mut file:fs::File = fs::OpenOptions::new(
    ).append(true
    ).read(true
    ).open("test.txt"
    ).expect("cannot open file");
file.write_all(b"append").expect("write failed");
file.seek(SeekFrom::Start(0))?;
file.read_to_string(&mut contents)?;
contents //"Hello, Rust!append"

在这里插入图片描述

更多推荐