• rust文件读写


    std::fs模块提供了结构体File,它表示一个文件。

    一、打开文件

    结构体File提供了open()函数
    open()以只读模式打开文件,如果文件不存在,则会抛出一个错误。如果文件不可读,那么也会抛出一个错误。

    范例

    fn main() {
         let file = std::fs::File::open("data.txt").unwrap();
         println!("文件打开成功:{:?}", file);
    }
    
    • 1
    • 2
    • 3
    • 4

    std::fs::File的open函数没有配套的close函数,因为Rust编译器可以在文件不再被使用时自动关闭文件。

    二、创建文件

    结构体File提供了create() 函数
    以只写模式打开文件。如果文件存在则清空旧内容;如果文件不存在则新建

    范例

    fn main() {
         let file = std::fs::File::create("data.txt").expect("create failed");
         println!("文件创建成功:{:?}",file);
    }
    
    • 1
    • 2
    • 3
    • 4

    三、读取文件

    (一)结构体File实现了Read特性
    Read特性提供了如下方法

    fn read(&mut self, buf: &mut [u8]) -> Result
    
    • 1

    读取一些字节到指定的缓冲区中,返回读取的字节数。读取的字节数等于缓冲区的长度

    fn read_to_end(&mut self, buf: &mut Vec) -> Result
    
    • 1

    读取所有字节,直到此源中的 EOF 为止,然后将它们追加到 buf

    fn read_to_string(&mut self, buf: &mut String) -> Result
    
    • 1

    读取所有字节,直到 EOF 为止,然后将它们追加到 buf。如果读取成功则返回读取的字节数,如果读取失败则抛出错误。

    实例

    use std::io::prelude::*;
    use std::fs;
    fn main() {
        let mut buffer = [0u8; 5];
        let mut file = fs::File::open("text.txt").unwrap();
        file.read(&mut buffer).unwrap();
        println!("{:?}", buffer);
        file.read(&mut buffer).unwrap();
        println!("{:?}", buffer);
    }
    运行结果:
    [84, 104, 105, 115, 32]
    [105, 115, 32, 97, 32]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    范例

    data.txt内容如下
    简单教程
    简单编程
    
    代码如下
    use std::io::Read;
    fn main(){
         let mut file = std::fs::File::open("data.txt").unwrap();
         let mut contents = String::new();
         file.read_to_string(&mut contents).unwrap();
         println!("{}", contents);
    }
    运行结果如下
    简单教程
    简单编程
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    (二)快捷函数
    std::fs::read_to_string

    pub fn read_to_string>(path: P) -> Result
    
    • 1

    将文件的全部内容读取为字符串。这是使用File::open和File::read_to_string 的便捷函数

    实例

    use std::fs;
    fn main() {
        let text = fs::read_to_string("text.txt").unwrap();
        println!("{}", text);
    }
    运行结果:
    This is a text file.
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    std::fs::read

    pub fn read>(path: P) -> Result>
    
    • 1

    将文件的全部内容读取为字节 vector。这是使用 File::open 和 read_to_end 的便捷函数

    实例

    use std::fs;
    fn main() {
        let content = fs::read("D:\\text.txt").unwrap();
        println!("{:?}", content);
    }
    运行结果:
    [84, 104, 105, 115, 32, 105, 115, 32, 97, 32, 116, 101, 120, 116, 32, 102, 105, 108, 101, 46]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    以上两种方式是一次性读取,十分适合Web应用的开发。但是更多情况下文件的大小可能远超内存容量。所以不常使用。

    四、写入文件

    (一)结构体File实现了Write特性
    Write特性提供了如下方法

    fn write(&mut self, buf: &[u8]) -> Result
    
    • 1

    写入一个缓冲区,返回写入的字节数。这个函数会尝试写入 buf 的全部内容,但是整个写入可能不会成功,或者写入也会产生错误。

    fn write_all(&mut self, buf: &[u8]) -> Result<()>
    
    • 1

    将整个缓冲区写入File。此方法将连续调用 write,直到没有更多数据要写入或返回非 ErrorKind::Interrupted 类型的错误为止。 在成功写入整个缓冲区或发生此类错误之前,此方法将不会返回

    实例

    use std::io::prelude::*;
    use std::fs::File;
    fn main() {
        let mut file = File::create("text.txt").unwrap();
        file.write(b"FROM RUST PROGRAM").unwrap();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    范例

    use std::io::Write;
    fn main() {
         let mut file = std::fs::File::create("data.txt").expect("create failed");
         file.write_all("简单教程".as_bytes()).expect("write failed");
         file.write_all("\n简单编程".as_bytes()).expect("write failed");
         println!("data written to file" );
    }
    编译运行,则data.txt的内容如下
    简单教程
    简单编程
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    (二)快捷函数
    std::fs::write

    pub fn write, C: AsRef<[u8]>>(path: P, contents: C) -> Result<()>
    
    • 1

    把一个切片写入文件,如果文件不存在就会创建文件,如果文件存在就替换其内容。
    这是使用 File::create 和 write_all 的便捷函数

    实例

    use std::fs;
    fn main() {
        fs::write("text.txt", "FROM RUST PROGRAM").unwrap();
    }
    
    • 1
    • 2
    • 3
    • 4

    执行程序之后,text.txt文件的内容将会被重写为FROM RUST PROGRAM。

    五、追加内容到文件末尾

    Write特性并没有提供函数用于追加内容
    但std::fs::OpenOptions结构体,可以配置文件打开方式。
    OpenOptions提供了append()用于设置追加模式

    pub fn append(&mut self, append: bool) -> &mut Self
    
    • 1

    当文件的模式设置为 追加 之后,写入文件的内容就不会代替原先的旧内容而是放在旧内容的后面。

    范例

    data.txt内容如下
    简单教程
    简单编程
    
    代码如下
    use std::fs::OpenOptions;
    use std::io::Write;
    fn main() {
         let mut file = OpenOptions::new().append(true).open("data.txt").expect("cannot open file");
         file.write_all("www.twle.cn".as_bytes()).expect("write failed");
         file.write_all("\n简单教程".as_bytes()).expect("write failed");
         file.write_all("\n简单编程".as_bytes()).expect("write failed");
         println!("数据追加成功");
    }
    运行结果如下
    数据追加成功
    
    打开  data.txt  文件,可以看到内容如下
    简单教程
    简单编程www.twle.cn
    简单教程
    简单编程
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    OpenOptions除append权限以外还有read权限和write权限,如果我们想以读写权限打开一个文件可以这样写

    实例

    text.txt内容如下
    this is text
    
    代码如下
    use std::io::prelude::*;
    use std::fs::OpenOptions;
    fn main() -> std::io::Result<()> {
        let mut file = OpenOptions::new().read(true).write(true).open("text.txt")?;
        file.write(b"COVER")?;
        Ok(())
    }
    运行之后,text.txt文件内容将变成:
    COVERis text
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    六、删除文件

    std::fs 提供了函数 remove_file() 用于删除文件。

    pub fn remove_file(path: P) -> Result<()>
    
    • 1

    注意,删除可能会失败,即使返回结果为OK,也有可能不会立即就删除。

    范例

    use std::fs;
    fn main() {
         fs::remove_file("data.txt").expect("could not remove file");
         println!("file is removed");
    }
    编译运行结果如下
    file is removed
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    打开当前目录,我们可以发现文件已经被删除了。

    七、复制文件

    Rust标准库没有提供任何函数用于复制一个文件为另一个新文件。
    但我们可以使用上面提到的函数和方法来实现文件的复制功能。
    下面的代码,我们模仿简单版本的 copy 命令

    copy old_file_name new_file_name
    
    • 1

    代码如下

    use std::io::Read;
    use std::io::Write;
    fn main() {
         let mut command_line: std::env::Args = std::env::args();
         command_line.next().unwrap();     // 跳过程序名
         // 原文件
         let source = command_line.next().unwrap();
         // 新文件
         let destination = command_line.next().unwrap();
         let mut file_in = std::fs::File::open(source).unwrap();
         let mut file_out = std::fs::File::create(destination).unwrap();
         let mut buffer = [0u8; 4096];
         loop {
             let nbytes = file_in.read(&mut buffer).unwrap();
             file_out.write(&buffer[..nbytes]).unwrap();
             if nbytes < buffer.len() { break; }
         }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    $ ./main data.txt data_new.txt
    
    • 1

    data.txt 为我们想要复制的原文件路径
    data_new.txt 为我们想要的新文件路径

  • 相关阅读:
    【算法挨揍日记】day15——560. 和为 K 的子数组、974. 和可被 K 整除的子数组
    ELA--学习笔记
    shiro反序列化漏洞复现(CVE-2016-4437)
    百度百科创建基础概念分享,为什么百度百科那么难做
    高德地图系列(三):vue项目利用高德地图实现地址搜索功能
    [ C++ ] C++之模板template
    springBoot复杂对象表示和lombok的使用
    《跟我一起学“网络安全”》——等保风评加固应急响应
    ECA-Net(Efficient Channel Attention Network)
    IDEA Debug步入(Step In)进不去源码解决方案
  • 原文地址:https://blog.csdn.net/inxunxun/article/details/133756936