2 个版本

0.1.1 2023 年 1 月 13 日
0.1.0 2023 年 1 月 13 日

1243Rust 模式

MIT 许可证

50KB
773

versioned-file

此说明是从 Rust 文档复制粘贴的,可能已过时。

VersionedFile 包提供了对 async_std::File 的包装,在文件中添加了一个不可见的 4096 字节头,用于跟踪文件版本号和文件标识符等信息。当使用 seekset_len 等方法时,会忽略该头部。例如,调用 set_len(0) 将导致文件具有逻辑大小为 0,但 4096 字节的文件头部仍然完好无损。

头部最有用的部分是版本号,它允许软件轻松检测文件是否使用过时的版本,并在该文件上完成更新。头部另一部分是标识符,这有助于在文件名称意外更改或丢失的情况下恢复文件。

当打开 VersionedFile 时,调用者传入文件的最新版本,以及一系列可以用于将旧版本文件升级到最新版本的升级方案。最后,还提供了标识符,以便在文件具有错误的标识符时抛出错误。

// Basic file operations
use async_std::io::SeekFrom;
use std::path::PathBuf;

use anyhow::{bail, Result, Error};
use versioned_file::{open_file, wrap_upgrade_process, Upgrade, VersionedFile};

#[async_std::main]
async fn main() {
    // Create a file with open_file:
    let path = PathBuf::from("target/docs-example-file.txt");
    let identifier = "VersionedFileDocs::example.txt";
    let mut versioned_file = open_file(&path, identifier, 1, &Vec::new()).await.unwrap();

    // Use write_all and read_exact for read/write operations:
    versioned_file.write_all(b"hello, world!").await.unwrap();
    versioned_file.seek(SeekFrom::Start(0)).await.unwrap();
    let mut buf = vec![0u8; versioned_file.len().await.unwrap() as usize];
    versioned_file.read_exact(&mut buf).await.unwrap();
    if buf != b"hello, world!" {
        panic!("example did not read correctly");
    }
}
// Simple upgrade example
use async_std::io::SeekFrom;
use std::path::PathBuf;

use anyhow::{bail, Result, Error};
use versioned_file::{open_file, wrap_upgrade_process, Upgrade, VersionedFile};

// An example of a function that upgrades a file from version 1 to version 2, while making
// changes to the body of the file.
async fn example_upgrade(
    mut vf: VersionedFile,
    initial_version: u8,
    updated_version: u8,
) -> Result<(), Error> {
    // Check that the version is okay.
    if initial_version != 1 || updated_version != 2 {
        bail!("wrong version");
    }

    // Truncate the file and replace the data
    vf.set_len(0).await.unwrap();
    let new_data = b"hello, update!";
    vf.write_all(new_data).await.unwrap();
    Ok(())
}

#[async_std::main]
async fn main() {
    // Open a file with an upgrade process:
    let path = PathBuf::from("target/docs-example-file.txt");
    let identifier = "VersionedFileDocs::example.txt";
    let upgrade = Upgrade {
        initial_version: 1,
        updated_version: 2,
        process: wrap_upgrade_process(example_upgrade),
    };
    let mut vf = open_file(&path, identifier, 2, &vec![upgrade]).await.unwrap();
    let mut buf = vec![0u8; vf.len().await.unwrap() as usize];
    vf.read_exact(&mut buf).await.unwrap();
    if buf != b"hello, update!" {
        panic!("example did not update correctly");
    }

    // Clean-up
    std::fs::remove_file(PathBuf::from("target/docs-example-file.txt"));
}

依赖项

~9–20MB
~296K SLoC