Rust高性能压缩库cloudflare-zlib-sys的使用:Cloudflare优化的zlib系统绑定,提供快速数据压缩与解压
Rust高性能压缩库cloudflare-zlib-sys的使用:Cloudflare优化的zlib系统绑定,提供快速数据压缩与解压
简介
cloudflare-zlib-sys是Cloudflare优化的zlib C实现的Rust绑定库。该库为64位ARM和Intel CPU构建zlib实现,要求x86-64 CPU支持SSE 4.2或ARM64支持NEON & CRC。不支持32位架构。
该库的API/ABI与原始Zlib保持相同。
安装
在项目目录中运行以下Cargo命令:
cargo add cloudflare-zlib-sys
或者在Cargo.toml中添加以下行:
cloudflare-zlib-sys = "0.3.6"
示例代码
以下是一个使用cloudflare-zlib-sys进行数据压缩和解压的完整示例:
use cloudflare_zlib_sys::*;
use std::ffi::CString;
use std::ptr;
fn main() {
// 原始数据
let original_data = b"Hello, this is a test string for zlib compression and decompression!";
// 压缩数据
let compressed_data = compress_data(original_data);
println!("Compressed size: {}", compressed_data.len());
// 解压数据
let decompressed_data = decompress_data(&compressed_data);
println!("Decompressed data: {:?}", String::from_utf8_lossy(&decompressed_data));
}
fn compress_data(data: &[u8]) -> Vec<u8> {
// 初始化zlib流
let mut stream: z_stream = unsafe { std::mem::zeroed() };
// 设置输出缓冲区
let mut out_buffer = vec![0; data.len()];
unsafe {
// 初始化压缩
deflateInit_(
&mut stream as *mut _,
Z_DEFAULT_COMPRESSION,
CString::new("1.2.11").unwrap().as_ptr(),
std::mem::size_of::<z_stream>() as i32,
);
// 设置输入数据
stream.next_in = data.as_ptr() as *mut _;
stream.avail_in = data.len() as u32;
// 设置输出缓冲区
stream.next_out = out_buffer.as_mut_ptr();
stream.avail_out = out_buffer.len() as u32;
// 执行压缩
deflate(&mut stream as *mut _, Z_FINISH);
// 结束压缩
deflateEnd(&mut stream as *mut _);
// 调整输出缓冲区大小以匹配实际压缩数据大小
out_buffer.set_len(stream.total_out as usize);
}
out_buffer
}
fn decompress_data(data: &[u8]) -> Vec<u8> {
// 初始化zlib流
let mut stream: z_stream = unsafe { std::mem::zeroed() };
// 设置输出缓冲区(初始大小为压缩数据的4倍)
let mut out_buffer = vec![0; data.len() * 4];
unsafe {
// 初始化解压
inflateInit_(
&mut stream as *mut _,
CString::new("1.2.11").unwrap().as_ptr(),
std::mem::size_of::<z_stream>() as i32,
);
// 设置输入数据
stream.next_in = data.as_ptr() as *mut _;
stream.avail_in = data.len() as u32;
// 设置输出缓冲区
stream.next_out = out_buffer.as_mut_ptr();
stream.avail_out = out_buffer.len() as u32;
// 执行解压
inflate(&mut stream as *mut _, Z_FINISH);
// 结束解压
inflateEnd(&mut stream as *mut _);
// 调整输出缓冲区大小以匹配实际解压数据大小
out_buffer.set_len(stream.total_out as usize);
}
out_buffer
}
完整示例代码
以下是基于上述示例的完整实现,增加了错误处理和更详细的注释:
use cloudflare_zlib_sys::*;
use std::ffi::CString;
use std::io::{self, Error, ErrorKind};
fn main() -> io::Result<()> {
// 原始数据
let original_data = b"Hello, this is a longer test string for zlib compression and decompression with cloudflare-zlib-sys!";
println!("Original data size: {} bytes", original_data.len());
// 压缩数据
let compressed_data = compress_data(original_data)?;
println!("Compressed size: {} bytes (ratio: {:.2}%)",
compressed_data.len(),
(compressed_data.len() as f32 / original_data.len() as f32) * 100.0
);
// 解压数据
let decompressed_data = decompress_data(&compressed_data)?;
println!("Decompressed size: {} bytes", decompressed_data.len());
// 验证数据完整性
if original_data == decompressed_data.as_slice() {
println!("Data integrity verified successfully!");
Ok(())
} else {
Err(Error::new(ErrorKind::InvalidData, "Decompressed data does not match original"))
}
}
fn compress_data(data: &[u8]) -> io::Result<Vec<u8>> {
// 初始化zlib流结构体
let mut stream: z_stream = unsafe { std::mem::zeroed() };
// 创建输出缓冲区,初始大小与输入相同(压缩后通常会更小)
let mut out_buffer = vec![0; data.len()];
unsafe {
// 初始化压缩流
let version = CString::new("1.2.11").unwrap();
let result = deflateInit_(
&mut stream as *mut _,
Z_DEFAULT_COMPRESSION, // 使用默认压缩级别
version.as_ptr(),
std::mem::size_of::<z_stream>() as i32
);
if result != Z_OK {
return Err(Error::new(ErrorKind::Other, "Failed to initialize zlib compression"));
}
// 设置输入数据指针和长度
stream.next_in = data.as_ptr() as *mut _;
stream.avail_in = data.len() as u32;
// 设置输出缓冲区指针和长度
stream.next_out = out_buffer.as_mut_ptr();
stream.avail_out = out_buffer.len() as u32;
// 执行压缩操作,使用Z_FINISH表示这是最后一块数据
let result = deflate(&mut stream as *mut _, Z_FINISH);
if result != Z_STREAM_END {
deflateEnd(&mut stream as *mut _);
return Err(Error::new(ErrorKind::Other, "Compression failed"));
}
// 结束压缩流
if deflateEnd(&mut stream as *mut _) != Z_OK {
return Err(Error::new(ErrorKind::Other, "Failed to end compression stream"));
}
// 调整输出缓冲区大小以匹配实际压缩数据大小
out_buffer.set_len(stream.total_out as usize);
}
Ok(out_buffer)
}
fn decompress_data(data: &[u8]) -> io::Result<Vec<u8>> {
// 初始化zlib流结构体
let mut stream: z_stream = unsafe { std::mem::zeroed() };
// 创建输出缓冲区,初始大小是压缩数据的4倍(解压后数据通常比压缩数据大)
let mut out_buffer = vec![0; data.len() * 4];
unsafe {
// 初始化解压流
let version = CString::new("1.2.11").unwrap();
let result = inflateInit_(
&mut stream as *mut _,
version.as_ptr(),
std::mem::size_of::<z_stream>() as i32
);
if result != Z_OK {
return Err(Error::new(ErrorKind::Other, "Failed to initialize zlib decompression"));
}
// 设置输入数据指针和长度
stream.next_in = data.as_ptr() as *mut _;
stream.avail_in = data.len() as u32;
// 设置输出缓冲区指针和长度
stream.next_out = out_buffer.as_mut_ptr();
stream.avail_out = out_buffer.len() as u32;
// 执行解压操作,使用Z_FINISH表示这是最后一块数据
let result = inflate(&mut stream as *mut _, Z_FINISH);
if result != Z_STREAM_END {
inflateEnd(&mut stream as *mut _);
return Err(Error::new(ErrorKind::Other, "Decompression failed"));
}
// 结束解压流
if inflateEnd(&mut stream as *mut _) != Z_OK {
return Err(Error::new(ErrorKind::Other, "Failed to end decompression stream"));
}
// 调整输出缓冲区大小以匹配实际解压数据大小
out_buffer.set_len(stream.total_out as usize);
}
Ok(out_buffer)
}
注意事项
- 该库需要64位CPU架构支持
- 对于Intel CPU,需要支持SSE 4.2指令集
- 对于ARM CPU,需要支持NEON和CRC指令
- 32位架构不受支持
许可证
该库使用Zlib许可证。
1 回复
以下是根据提供的内容整理的完整指南,包含示例代码和详细说明:
Rust高性能压缩库cloudflare-zlib-sys使用指南
简介
cloudflare-zlib-sys
是Cloudflare优化的zlib系统绑定库,提供了比标准zlib更快速的数据压缩与解压功能。这个库是Cloudflare对zlib进行性能优化后的Rust绑定版本,特别适合需要高性能压缩/解压的场景。
主要特性
- 比标准zlib更快的压缩和解压速度
- 与标准zlib API兼容
- 针对现代CPU架构优化
- 支持所有标准zlib压缩级别
安装方法
在Cargo.toml中添加依赖:
[dependencies]
cloudflare-zlib-sys = "1.1.0"
完整示例代码
use cloudflare_zlib_sys::*;
use std::ffi::CString;
use std::os::raw::c_uint;
use std::mem;
fn main() {
// 示例数据
let data = b"This is a test string to demonstrate compression and decompression with cloudflare-zlib-sys";
// 压缩数据
let compressed = compress_data(data);
println!("Compressed size: {} (from {})", compressed.len(), data.len());
// 解压数据
if let Some(decompressed) = decompress_data(&compressed, data.len()) {
println!("Decompressed matches original: {}", decompressed == data);
} else {
println!("Decompression failed!");
}
// 流式压缩示例
let stream_compressed = stream_compress(data);
println!("Stream compressed size: {}", stream_compressed.len());
}
// 基础压缩函数
fn compress_data(input: &[u8]) -> Vec<u8> {
// 估算输出缓冲区大小
let bound = unsafe { compressBound(input.len() as c_uint) };
let mut output = vec![0u8; bound as usize];
let mut out_len = bound;
unsafe {
compress(
output.as_mut_ptr(),
&mut out_len,
input.as_ptr(),
input.len() as c_uint,
Z_DEFAULT_COMPRESSION,
);
}
output.truncate(out_len as usize);
output
}
// 基础解压函数
fn decompress_data(compressed: &[u8], original_size: usize) -> Option<Vec<u8>> {
let mut output = vec![0u8; original_size];
let mut out_len = original_size as c_uint;
let result = unsafe {
uncompress(
output.as_mut_ptr(),
&mut out_len,
compressed.as_ptr(),
compressed.len() as c_uint,
)
};
if result == Z_OK {
output.truncate(out_len as usize);
Some(output)
} else {
None
}
}
// 流式压缩函数
fn stream_compress(input: &[u8]) -> Vec<u8> {
let mut stream: z_stream = unsafe { mem::zeroed() };
let mut output = Vec::with_capacity(input.len() / 2);
let mut out_buf = [0u8; 1024];
unsafe {
deflateInit_(&mut stream, Z_DEFAULT_COMPRESSION,
CString::new("1.2.11").unwrap().as_ptr(),
mem::size_of::<z_stream>() as i32);
stream.next_in = input.as_ptr() as *mut _;
stream.avail_in = input.len() as c_uint;
loop {
stream.next_out = out_buf.as_mut_ptr() as *mut _;
stream.avail_out = out_buf.len() as c_uint;
let ret = deflate(&mut stream, Z_FINISH);
let produced = out_buf.len() - stream.avail_out as usize;
output.extend_from_slice(&out_buf[..produced]);
if ret == Z_STREAM_END {
break;
}
}
deflateEnd(&mut stream);
}
output
}
性能建议
-
对于大文件,使用流式处理(如上面的示例)而不是一次性处理
-
根据数据类型选择合适的压缩级别:
Z_NO_COMPRESSION
: 最快但不压缩Z_BEST_SPEED
: 快速压缩Z_DEFAULT_COMPRESSION
: 平衡压缩率和速度Z_BEST_COMPRESSION
: 最高压缩率但较慢
-
重用z_stream结构体以避免重复分配内存
错误处理
所有函数返回Z_OK(0)表示成功,其他值表示错误。常见错误码:
pub const Z_OK: i32 = 0;
pub const Z_STREAM_END: i32 = 1;
pub const Z_NEED_DICT: i32 = 2;
pub const Z_ERRNO: i32 = -1;
pub const Z_STREAM_ERROR: i32 = -2;
pub const Z_DATA_ERROR: i32 = -3;
pub const Z_MEM_ERROR: i32 = -4;
pub const Z_BUF_ERROR: i32 = -5;
pub const Z_VERSION_ERROR: i32 = -6;
注意事项
- 这个库是zlib的系统绑定,使用时需要系统安装zlib库
- 在多线程环境中使用时,每个线程应该使用自己的z_stream结构体
- 压缩和解压时使用相同的压缩级别和策略可以获得最佳性能
通过使用cloudflare-zlib-sys,你可以在Rust应用中享受到Cloudflare优化的zlib性能,特别适合网络服务、数据处理等高性能场景。