The file path

To open or create a file, first specify the path to the file.

Path manipulation in Rust is cross-platform, and the STD :: Path module provides two types to describe paths:

  • PathBufHas ownership and can be modified, similar toString.
  • Path— Path slice, similar tostr.

Example:

use std::path::Path;
use std::path::PathBuf;
fn main() {
    // Wrap a string slice directly into a path slice
    let path = Path::new("./foo/bar.txt");

    // Returns the parent path, or 'None' if there is no parent path
    let parent = path.parent().unwrap();

    // Return the file name (excluding the file extension)
    let file_stem = path.file_stem().unwrap();

    println!(
        "path: {:? }, parent: {:? }, file_stem: {:? }",
        path, parent, file_stem
    );

    // Create an empty 'PathBuf'
    let mut empty_path = PathBuf::new();
    println!("empty_path: {:? }", empty_path);

    // Create 'PathBuf' based on the string slice
    let path = PathBuf::from(r"C:\windows\system32.dll");

    // Add a path
    empty_path.push(r"C:\");

    println!("empty_path: {:? }, path: {:? }", empty_path, path);
}
Copy the code

File creation and deletion

Rust’s STD :: FS module provides functionality for a range of file system operations.

Directory creation and deletion

Create directory function:

  • create_dir<P: AsRef<Path>>(path: P) -> Result<()>Creates an empty directory, returns an error if the specified path does not exist.
  • create_dir_all<P: AsRef<Path>>(path: P) -> Result<()>— Create directories in cascades.

Example:

use std::fs;
// Since string slices implement the 'AsRef
      
       ' Trait, arguments in functions can use string literals directly
      
fn main() -> std::io::Result< > () {Create an empty directory
    fs::create_dir("./empty")? ;// Create a directory. If the parent directory does not exist, create it together
    fs::create_dir_all("./some/dir")? ;Ok(())}Copy the code

Delete directory function:

  • remove_dir<P: AsRef<Path>>(path: P) -> Result<()>— Deletes the specified empty directory.
  • remove_dir_all<P: AsRef<Path>>(path: P) -> Result<()>— Deletes the specified directory and its contents.

Example:

use std::fs;

fn main() -> std::io::Result< > () {// Delete an empty directory
    fs::remove_dir("./empty")? ;// Deletes the specified directory and its contents, but does not delete its parent directory
    fs::remove_dir_all("./some/dir")? ;Ok(())}Copy the code

File creation and deletion

Rust uses the STD ::fs::File structure to associate with files in a File system, which can be read and written from STD :: FS ::File instances.

File creation and deletion functions:

  • create<P: AsRef<Path>>(path: P) -> Result<File>
  • std::fs::remove_file<P: AsRef<Path>>(path: P) -> Result<()>

Example:

use std::fs;
use std::fs::File;

fn main() -> std::io::Result< > () {// Open the specified file in write only mode, empty the file if it exists, and create a new file if it does not exist
    let mut f = File::create("foo.txt")? ;// Delete files
    fs::remove_file("foo.txt")? ;Ok(())}Copy the code

File reads and writes

STD ::fs::File itself implements Read and Write traits, so reading and writing files is straightforward.

File open

Before reading or writing a File, you should first get an instance of type File. In addition to getting an instance of File when creating a File, you can also use the open function for File:

  • open<P: AsRef<Path>>(path: P) -> Result<File>

Example:

use std::fs::File;

fn main() -> std::io::Result< > () {// Open the specified file in read-only mode. An error is returned if the file does not exist
    let _file = File::open("foo.txt")? ;Ok(())}Copy the code

File instances obtained using the create and open functions are read-only or write-only. If you want to control more read and write options, you need to use STD ::fs::OpenOptions. It’s a Builder, the same Builder that underlies the create and open functions.

When using STD ::fs::OpenOptions, OpenOptions::new is called first, then the read and write options are set through a chain call, and finally OpenOptions::open is called to open the specified file.

Example:

use std::fs::OpenOptions;

fn main() -> std::io::Result< > () {let _file = OpenOptions::new()
        .read(true)
        .write(true)
        .create(true) // Create a new file, open the file if it exists
        .open("foo.txt")? ;let _file = OpenOptions::new()
        .append(true) // Append content
        .open("foo.txt")? ;let _file = OpenOptions::new()
        .write(true)
        .truncate(true) // Clear the file
        .open("foo.txt");

    Ok(())}Copy the code

File to read

The file is Read primarily using functions in STD :: IO ::Read traits. Such as:

  • read(&mut self, buf: &mut [u8]) -> Result<usize>
  • read_to_string(&mut self, buf: &mut String) -> Result<usize>

Example:

use std::fs::File;
use std::io;
// The 'Prelude' module contains the IO traits commonly used: 'BufRead', 'Read', 'Write', 'Seek'
use std::io::prelude::*;

fn main() -> io::Result< > () {let mut f = File::open("foo.txt")? ;let mut buffer = [0; 10];
    // Read the first 10 bytes of the file
    let n = f.read(&mutbuffer[..] )? ;println!("The bytes: {:? }", &buffer[..n]);

    // Then read 10 bytes
    let n = f.read(&mutbuffer[..] )? ;println!("The bytes: {:? }", &buffer[..n]);

    let mut f = File::open("foo.txt")? ;let mut buffer = String::new();
    // Read all the contents of the file and convert it to a character string. If the file is not in UTF-8 format, an error is reported
    f.read_to_string(&mutbuffer)? ;println!("The string: {}", buffer);

    Ok(())}Copy the code

In addition, the File type implements STD :: IO ::Seek Trait, which primarily provides a Seek function that controls where files are read and written to start.

  • seek(&mut self, pos: SeekFrom) -> Result<u64>

Example:

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")? ;// Move the cursor forward 10 bytes (default cursor position is 0)
    f.seek(SeekFrom::Start(10))? ;// Read anything after the first 10 bytes into Buf
    let mut buffer = String::new();
    f.read_to_string(&mutbuffer)? ;println!("The string: {}", buffer);

    Ok(())}Copy the code

In addition to setting the starting point of a file read, you can also limit the length of a file read. STD :: IO ::Read provides the take function to limit the length of a file Read.

  • take(self, limit: u64) -> Take<Self>

Example:

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];

    // Limit the read length to 5 bytes at most
    let mut handle = f.take(5);

    handle.read(&mutbuffer)? ;println!("buffer: {:? }", buffer);

    Ok(())}Copy the code

File is written to

The files are read primarily using functions in STD :: IO ::Write traits. Such as:

  • fn write(&mut self, buf: &[u8]) -> Result<usize>Attempts to write the entire contents of Buf to a file may fail.
  • fn flush(&mut self) -> Result<()>
  • fn write_all(&mut self, buf: &[u8]) -> Result<()>— Continuous callwrite, writes everything in the Buf to a file.

Example:

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(())}Copy the code

The relevant data

The Rust Standard Library

Rust By Example

RustPrimer