2 个版本
0.1.1 | 2023 年 1 月 13 日 |
---|---|
0.1.0 | 2023 年 1 月 13 日 |
1243 在 Rust 模式
50KB
773 行
versioned-file
此说明是从 Rust 文档复制粘贴的,可能已过时。
VersionedFile 包提供了对 async_std::File 的包装,在文件中添加了一个不可见的 4096 字节头,用于跟踪文件版本号和文件标识符等信息。当使用 seek
和 set_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