7 个版本 (2 个稳定版)

使用旧的 Rust 2015

1.0.1 2020 年 8 月 17 日
1.0.0 2019 年 11 月 2 日
0.2.1 2018 年 4 月 14 日
0.2.0 2017 年 8 月 7 日
0.0.0 2017 年 8 月 3 日

#388算法

Download history 88/week @ 2024-03-11 69/week @ 2024-03-18 104/week @ 2024-03-25 126/week @ 2024-04-01 50/week @ 2024-04-08 47/week @ 2024-04-15 64/week @ 2024-04-22 111/week @ 2024-04-29 98/week @ 2024-05-06 131/week @ 2024-05-13 86/week @ 2024-05-20 58/week @ 2024-05-27 80/week @ 2024-06-03 48/week @ 2024-06-10 39/week @ 2024-06-17 57/week @ 2024-06-24

229 每月下载量
11 包(4 个直接使用) 中使用

MIT 许可证

27KB
431

Build Status Crates.io Documentation Say Thanks!

内容定义分块

该包提供了一种将字节流划分为块的方法,这些方法通过从内容本身选择分割点来实现。这意味着在流中添加或删除几个字节只会改变直接修改的块。这与仅仅每 n 个字节分割不同,因为在那种情况下,除非改变的字节数是 n 的倍数,否则每个块都不同。

内容定义分块对于数据去重很有用。它被用于许多备份软件,以及 rsync 数据同步工具。

该包公开了易于使用的功能,实现了标准 Iterator 特性,以便在输入流上迭代块,以及高效的零分配方法,这些方法重用内部缓冲区。

使用此包

首先,通过在您的 Cargo.toml 中添加以下内容来添加对包的依赖项

cdchunking = 1.0

并在您的 lib.rs

extern crate cdchunking;

然后使用特定方法创建一个 Chunker 对象,例如 ZPAQ 算法

use cdchunking::{Chunker, ZPAQ};

let chunker = Chunker::new(ZPAQ::new(13)); // 13 bits = 8 KiB block average

有几种方法可以从一些输入数据中获取块。

从内存缓冲区:迭代切片

如果您的整个输入数据都存储在内存中,您可以使用 slices() 方法。它将返回一个迭代器,该迭代器在缓冲区的切片上迭代,允许处理这些块而无需额外的分配。

for slice in chunker.slices(data) {
    println("{:?}", slice);
}

从文件对象:将块读入内存

如果您正在从文件读取,或任何实现了 Read 接口的对象中读取,您可以使用 Chunker 直接读取整个数据块。使用 whole_chunks() 方法来获取数据块的迭代器,并以新的 Vec<u8> 对象的形式读取。

for chunk in chunker.whole_chunks(reader) {
    let chunk = chunk.expect("Error reading from file");
    println!("{:?}", chunk);
}

您还可以使用 all_chunks() 方法从文件中读取所有数据块并将它们收集到一个 VecVec 的向量)中。它将为您处理IO错误,如果任何一个数据块读取失败,将返回错误。

let chunks: Vec<Vec<u8>> = chunker.all_chunks(reader)
    .expect("Error reading from file");
for chunk in chunks {
    println!("{:?}", chunk);
}

从文件对象:零分配流式传输数据块

如果您正在从文件读取以写入到另一个地方,您可能认为分配中间 Vec 对象是不必要的。如果您希望 Chunker 从内部读取缓冲区提供数据块,而不分配任何其他内容,则可以这样做。在这种情况下,请注意,一个数据块可能会在多个读取操作之间分割。此方法可以适用于任何大小的数据块。

使用 stream() 方法来完成此操作。请注意,由于内部缓冲区被重复使用,我们无法实现 Iterator 特性,因此您需要使用 while 循环。

let mut chunk_iterator = chunker.stream(reader);
while let Some(chunk) = chunk_iterator.read() {
    let chunk = chunk.unwrap();
    match chunk {
        ChunkInput::Data(d) => {
            print!("{:?}, ", d);
        }
        ChunkInput::End => println!(" end of chunk"),
    }
}

无运行时依赖