Файловые операции в Rust

Rust

Путь файла

Чтобы открыть или создать файл, сначала укажите путь к файлу.

Операции с путями в Rust являются кроссплатформенными.std::pathВ модуле предусмотрено два типа описания путей:

  • PathBuf-- принадлежащий и изменяемый, аналогичныйString.
  • Path-- фрагменты пути, аналогичныеstr.

Пример:

use std::path::Path;
use std::path::PathBuf;
fn main() {
    // 直接将一个字符串切片包装成一个路径切片
    let path = Path::new("./foo/bar.txt");

    // 返回上级路径,若无上级路径则返回 `None`
    let parent = path.parent().unwrap();

    // 返回文件名(不包含文件扩展名)
    let file_stem = path.file_stem().unwrap();

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

    // 创建一个空的 `PathBuf`
    let mut empty_path = PathBuf::new();
    println!("empty_path: {:?}", empty_path);

    // 根据字符串切片创建 `PathBuf`
    let path = PathBuf::from(r"C:\windows\system32.dll");

    // 添加路径
    empty_path.push(r"C:\");

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

Создание и удаление файлов

ржавчиныstd::fsМодули обеспечивают функциональность для ряда операций с файловой системой.

Создание и удаление каталога

Функция для создания каталога:

  • create_dir<P: AsRef<Path>>(path: P) -> Result<()>-- Создает пустой каталог или возвращает ошибку, если указанный путь не существует.
  • create_dir_all<P: AsRef<Path>>(path: P) -> Result<()>-- Каскадное создание каталогов.

Пример:

use std::fs;
// 由于字符串切片实现了 `AsRef<Path>` Trait,因此函数中的参数可以直接使用字符串字面量
fn main() -> std::io::Result<()> {
    // 创建一个空目录
    fs::create_dir("./empty")?;

    // 创建一个目录,若其上级目录不存在,则一同创建
    fs::create_dir_all("./some/dir")?;

    Ok(())
}

Функция для удаления каталога:

  • remove_dir<P: AsRef<Path>>(path: P) -> Result<()>-- удалить указанный пустой каталог.
  • remove_dir_all<P: AsRef<Path>>(path: P) -> Result<()>-- Удалить указанный каталог и его содержимое.

Пример:

use std::fs;

fn main() -> std::io::Result<()> {
    // 删除一个空目录
    fs::remove_dir("./empty")?;

    // 删除指定目录及其目录下的内容,但不会删除其上级目录
    fs::remove_dir_all("./some/dir")?;

    Ok(())
}

Создание и удаление файлов

Ржавчина используетstd::fs::FileСтруктуры связаны с файлами в файловой системе черезstd::fs::FileЭкземпляры могут читать и записывать файлы.

Функции для создания и удаления файлов:

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

Пример:

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

fn main() -> std::io::Result<()> {
    // 以只写模式打开指定文件,若文件存在则清空文件内容,若文件不存在则新建一个
    let mut f = File::create("foo.txt")?;

    // 删除文件
    fs::remove_file("foo.txt")?;

    Ok(())
}

чтение и запись файлов

std::fs::Fileосознал себяReadиWriteЧерта, поэтому чтение и запись файлов очень проста.

файл открыть

Прежде чем читать или записывать файл, вы должны сначала получитьFileТип экземпляр. за исключением того, что вы можете получить его при создании файлаFileнапример, вы также можете использоватьFileизopenфункция:

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

Пример:

use std::fs::File;

fn main() -> std::io::Result<()> {
    // 以只读模式打开指定文件,若文件不存在则返回错误
    let _file = File::open("foo.txt")?;

    Ok(())
}

использоватьcreateиopenЭкземпляр файла, полученный функцией, доступен только для чтения или только для записи.Если вы хотите контролировать дополнительные параметры чтения и записи, вам нужно использоватьstd::fs::OpenOptions. Это Строитель,createиopenЭто также функция базового Builder.

использоватьstd::fs::OpenOptions, первый звонокOpenOptions::new, затем объединение вызовов для установки параметров чтения и записи и, наконец, вызовOpenOptions::openОткройте указанный файл.

Пример:

use std::fs::OpenOptions;

fn main() -> std::io::Result<()> {
    let _file = OpenOptions::new()
        .read(true)
        .write(true)
        .create(true) // 新建,若文件存在则打开这个文件
        .open("foo.txt")?;

    let _file = OpenOptions::new()
        .append(true) // 追加内容
        .open("foo.txt")?;

    let _file = OpenOptions::new()
        .write(true)
        .truncate(true) // 清空文件
        .open("foo.txt");

    Ok(())
}

Чтение файла

Чтение файлов в основномstd::io::ReadФункции в признаках. Например:

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

Пример:

use std::fs::File;
use std::io;
// `prelude` 模块包含通常使用的 IO Trait: `BufRead`, `Read`, `Write`, `Seek`
use std::io::prelude::*;

fn main() -> io::Result<()> {
    let mut f = File::open("foo.txt")?;
    let mut buffer = [0; 10];
    // 读取文件中的前10个字节
    let n = f.read(&mut buffer[..])?;
    println!("The bytes: {:?}", &buffer[..n]);

    // 接着读取10个字节
    let n = f.read(&mut buffer[..])?;
    println!("The bytes: {:?}", &buffer[..n]);

    let mut f = File::open("foo.txt")?;
    let mut buffer = String::new();
    // 读取文件所有内容并转为字符字符串,若文件非 UTF-8 格式,则会报错
    f.read_to_string(&mut buffer)?;
    println!("The string: {}", buffer);

    Ok(())
}

Кроме того,FileТип также реализуетstd::io::SeekЧерта характера,SeekВ основном обеспечиваетсяseekФункции, управляющие начальной позицией для чтения и записи файла.

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

Пример:

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")?;

    // 将游标前移 10 个字节(游标的默认位置是 0)
    f.seek(SeekFrom::Start(10))?;

    // 将前 10 个字节之后的内容读取到 Buf 中
    let mut buffer = String::new();
    f.read_to_string(&mut buffer)?;
    println!("The string: {}", buffer);

    Ok(())
}

Помимо установки начальной точки чтения файла, вы также можете ограничить продолжительность чтения файла.std::io::Readпри условииtakeФункция для ограничения длины чтения файлов.

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

Пример:

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

    // 限制读取长度最多为 5 字节
    let mut handle = f.take(5);

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

    Ok(())

}

запись в файл

Основное использование для чтения файловstd::io::WriteФункции в признаках. Например:

  • fn write(&mut self, buf: &[u8]) -> Result<usize>-- Попытка записать все содержимое Buf в файл, возможно, безуспешно.
  • fn flush(&mut self) -> Result<()>
  • fn write_all(&mut self, buf: &[u8]) -> Result<()>-- Продолжай звонитьwrite, записывает все в Buf в файл.

Пример:

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(())
}

Релевантная информация

The Rust Standard Library

Rust By Example

RustPrimer