Rust数据压缩库ppmd-rust的使用,ppmd-rust提供高性能PPMd压缩算法实现与解压功能

Rust数据压缩库ppmd-rust的使用

ppmd-rust是一个提供高性能PPMd压缩算法实现与解压功能的Rust库。它是从7-Zip中的PPMd C代码移植到Rust的实现。

提供的算法变体

  • PPMd7 (PPMdH):7z存档格式使用的版本
  • PPMd8 (PPMdI rev.1):zip存档格式使用的版本

注意事项

有两种正确限制未压缩数据的方法:

  1. 将未压缩大小与压缩数据一起保存,并使用std::io::Read::read_exact()读取数据(7z存档格式使用这种方法)
  2. 在完成编码过程时调用编码器的finish(true)来编码结束标记,然后可以使用std::io::Read::read_to_end()读取数据

如果不这样做,会导致实际数据末尾出现垃圾符号。

完整示例代码

use ppmd_rust::{Ppmd7Encoder, Ppmd7Decoder};
use std::io::{Read, Write};

fn main() -> std::io::Result<()> {
    // 原始数据
    let original_data = b"这是一段需要压缩的测试数据";
    
    // 压缩
    let mut encoder = Ppmd7Encoder::new(6, 16 * 1024 * 1024)?;
    encoder.write_all(original_data)?;
    let compressed_data = encoder.finish(false)?;
    
    // 解压
    let mut decoder = Ppmd7Decoder::new(&compressed_data[..])?;
    let mut decompressed_data = Vec::new();
    decoder.read_to_end(&mut decompressed_data)?;
    
    // 验证
    assert_eq!(original_data, decompressed_data.as_slice());
    
    Ok(())
}

更完整的示例代码

下面是一个更完整的示例,展示了如何处理文件压缩和解压:

use ppmd_rust::{Ppmd7Encoder, Ppmd7Decoder};
use std::fs::File;
use std::io::{self, Read, Write};

fn compress_file(input_path: &str, output_path: &str) -> io::Result<()> {
    // 读取要压缩的文件
    let mut input_file = File::open(input_path)?;
    let mut buffer = Vec::new();
    input_file.read_to_end(&mut buffer)?;
    
    // 创建压缩器 (模型阶数6,字典大小16MB)
    let mut encoder = Ppmd7Encoder::new(6, 16 * 1024 * 1024)?;
    
    // 压缩数据
    encoder.write_all(&buffer)?;
    let compressed_data = encoder.finish(true)?; // 使用结束标记
    
    // 写入压缩文件
    let mut output_file = File::create(output_path)?;
    output_file.write_all(&compressed_data)?;
    
    Ok(())
}

fn decompress_file(input_path: &str, output_path: &str) -> io::Result<()> {
    // 读取压缩文件
    let mut input_file = File::open(input_path)?;
    let mut compressed_data = Vec::new();
    input_file.read_to_end(&mut compressed_data)?;
    
    // 创建解压器
    let mut decoder = Ppmd7Decoder::new(&compressed_data[..])?;
    
    // 解压数据
    let mut decompressed_data = Vec::new();
    decoder.read_to_end(&mut decompressed_data)?;
    
    // 写入解压后的文件
    let mut output_file = File::create(output_path)?;
    output_file.write_all(&decompressed_data)?;
    
    Ok(())
}

fn main() -> io::Result<()> {
    let original_file = "example.txt";
    let compressed_file = "example.txt.ppmd";
    let decompressed_file = "example_decompressed.txt";
    
    // 压缩文件
    compress_file(original_file, compressed_file)?;
    println!("文件压缩完成");
    
    // 解压文件
    decompress_file(compressed_file, decompressed_file)?;
    println!("文件解压完成");
    
    Ok(())
}

安装

在项目目录中运行以下Cargo命令:

cargo add ppmd-rust

或者在Cargo.toml中添加:

ppmd-rust = "1.2.1"

许可证

该库的代码与原始作者的代码一样属于公共领域。


1 回复

Rust数据压缩库ppmd-rust的使用指南

ppmd-rust是一个提供高性能PPMd(Prediction by Partial Matching)压缩算法实现的Rust库。PPMd是一种基于上下文建模的压缩算法,特别适合文本数据的压缩。

特性

  • 纯Rust实现
  • 高性能PPMd压缩/解压
  • 支持多种压缩级别
  • 无依赖
  • 线程安全

添加依赖

在Cargo.toml中添加:

[dependencies]
ppmd-rust = "0.1"

基本用法

压缩数据

use ppmd_rust::{compress, CompressionLevel};

fn main() {
    let data = b"This is some sample text data that we want to compress using PPMd algorithm";
    
    // 使用默认压缩级别压缩数据
    let compressed_data = compress(data, CompressionLevel::Default).unwrap();
    
    println!("Original size: {} bytes", data.len());
    println!("Compressed size: {} bytes", compressed_data.len());
}

解压数据

use ppmd_rust::decompress;

fn main() {
    let compressed_data = /* 从某处获取压缩数据 */;
    
    let decompressed_data = decompress(&compressed_data).unwrap();
    
    println!("Decompressed data: {:?}", decompressed_data);
}

高级用法

自定义压缩级别

use ppmd_rust::{compress_with_level, CompressionLevel};

fn main() {
    let data = b"Large text data that needs optimal compression";
    
    // 使用最高压缩级别
    let compressed_data = compress_with_level(data, CompressionLevel::Maximum).unwrap();
    
    // 使用快速压缩级别
    let fast_compressed = compress_with_level(data, CompressionLevel::Fast).unwrap();
}

流式压缩

对于大文件处理,可以使用流式接口:

use ppmd_rust::{Compressor, Decompressor};
use std::io::{Read, Write};

fn compress_file(input: &mut dyn Read, output: &mut dyn Write) -> std::io::Result<()> {
    let mut compressor = Compressor::new(output, CompressionLevel::Default)?;
    std::io::copy(input, &mut compressor)?;
    compressor.finish()?;
    Ok(())
}

fn decompress_file(input: &mut dyn Read, output: &mut dyn Write) -> std::io::Result<()> {
    let mut decompressor = Decompressor::new(input)?;
    std::io::copy(&mut decompressor, output)?;
    Ok(())
}

性能提示

  1. 对于小数据块(小于1KB),PPMd可能不是最佳选择
  2. 文本数据压缩效果通常优于二进制数据
  3. 更高压缩级别需要更多内存和CPU时间

完整示例:压缩和解压文件

以下是一个完整的示例,演示如何使用ppmd-rust压缩和解压文件:

use ppmd_rust::{compress, decompress, CompressionLevel};
use std::fs;
use std::io::{self, Write};

fn main() -> io::Result<()> {
    // 1. 准备要压缩的文本数据
    let text = "这是一个用于测试PPMd压缩算法的文本数据。PPMd算法特别适合压缩文本数据,能提供较高的压缩比。";
    
    // 2. 创建输入文件
    fs::write("input.txt", text)?;
    println!("已创建input.txt文件");
    
    // 3. 读取文件内容并压缩
    let data = fs::read("input.txt")?;
    let compressed = compress(&data, CompressionLevel::Maximum)?;
    fs::write("compressed.ppmd", &compressed)?;
    println!("压缩完成,已保存为compressed.ppmd");
    
    // 4. 解压数据
    let decompressed = decompress(&compressed)?;
    fs::write("decompressed.txt", &decompressed)?;
    println!("解压完成,已保存为decompressed.txt");
    
    // 5. 验证数据完整性
    let original = fs::read("input.txt")?;
    let restored = fs::read("decompressed.txt")?;
    
    assert_eq!(original, restored);
    println!("验证通过:原始数据与解压后的数据完全一致");
    
    // 6. 显示压缩前后大小对比
    println!("原始大小: {} 字节", original.len());
    println!("压缩后大小: {} 字节", compressed.len());
    println!("压缩比: {:.2}%", (compressed.len() as f32 / original.len() as f32) * 100.0);
    
    Ok(())
}

注意事项

  • 压缩和解压必须使用相同的模型参数
  • 错误处理很重要,特别是对于损坏的压缩数据
  • 考虑使用缓冲IO来提高大文件处理的性能

ppmd-rust为Rust开发者提供了一个强大且高效的PPMd实现,特别适合需要高压缩比的文本数据处理场景。

回到顶部