读和写

从文件中,读取字符串行

std-badge cat-filesystem-badge

将一份三行的消息写入文件,然后由BufRead::lines,返回Lines迭代器,用来一次读取一行。 File实现了Read,也就是提供BufReader trait。File::create会打开一个File,用于写入(文件),而File::open用来读取。

use std::fs::File;
use std::io::{Write, BufReader, BufRead, Error};

fn main() -> Result<(), Error> {
    let path = "lines.txt";

    let mut output = File::create(path)?;
    write!(output, "Rust\n💖\nFun")?;

    let input = File::open(path)?;
    let buffered = BufReader::new(input);

    for line in buffered.lines() {
        println!("{}", line?);
    }

    Ok(())
}

避免写入和读取,同一文件

same_file-badge cat-filesystem-badge

使用same_file::Handle 控制一个文件,这样,该文件可以测试是否与其他 Handle(控制)的文件相等。在这个例子中,要读取和写入的文件 handle,被测试是否相等。

extern crate same_file;

use same_file::Handle;
use std::fs::File;
use std::io::{BufRead, BufReader, Error, ErrorKind};
use std::path::Path;

fn main() -> Result<(), Error> {
    let path_to_read = Path::new("new.txt");

    let stdout_handle = Handle::stdout()?;
    let handle = Handle::from_path(path_to_read)?;

    if stdout_handle == handle {
        return Err(Error::new(
            ErrorKind::Other,
            "You are reading and writing to the same file",
        ));
    } else {
        let file = File::open(&path_to_read)?;
        let file = BufReader::new(file);
        for (num, line) in file.lines().enumerate() {
            println!("{} : {}", num, line?.to_uppercase());
        }
    }

    Ok(())
}
cargo run

显示文件 new.txt 的内容。

cargo run >> ./new.txt

错误,因为两个文件相同。

使用内存映射,随机访问文件

memmap-badge cat-filesystem-badge

使用memmap创建文件的内存映射,并模拟一些文件的非顺序读取。使用内存映射,意味着您只需要索引到一个切片,而不是处理导航文件的seek

这个Mmap::map函数假定内存映射后面的文件,不会同时被另一个进程修改,或者竞争条件发生。

extern crate memmap;

use memmap::Mmap;
use std::fs::File;
use std::io::{Write, Error};

fn main() -> Result<(), Error> {
#     write!(File::create("content.txt")?, "My hovercraft is full of eels!")?;
#
    let file = File::open("content.txt")?;
    let map = unsafe { Mmap::map(&file)? };

    let random_indexes = [0, 1, 2, 19, 22, 10, 11, 29];
    assert_eq!(&map[3..13], b"hovercraft");
    let random_bytes: Vec<u8> = random_indexes.iter()
        .map(|&idx| map[idx])
        .collect();
    assert_eq!(&random_bytes[..], b"My loaf!");
    Ok(())
}