7 个版本 (重大更新)
0.6.0 | 2024年4月5日 |
---|---|
0.5.0 | 2023年11月24日 |
0.4.1 | 2022年6月20日 |
0.4.0 | 2022年5月4日 |
0.1.0 | 2018年2月20日 |
#184 在 解析器实现
68,206 每月下载量
用于 30 个crate (9 直接)
94KB
2K SLoC
rust-cab
一个用于读写 Windows CAB 文件的纯 Rust 库。
许可证
rust-cab 在 MIT 许可证 下提供。
lib.rs
:
一个用于读写 Windows CAB 文件的库。
概述
CAB 是 Windows 使用的存档文件格式。CAB 文件可以包含多个压缩文件,这些文件被分成“文件夹”(与文件系统文件夹/目录无关);同一文件夹中的文件被压缩在一起,CAB 文件中的每个文件夹都可能使用不同的压缩方案。CAB 文件格式支持多种不同的压缩方案;当读取现有 CAB 文件的元数据时,此库可以识别所有这些方案,但目前仅支持编码/解码其中一些,如下所示
压缩 | 支持 |
---|---|
未压缩 | 是 |
MSZIP (Deflate) | 是 |
Quantum | 否 |
LZX | 是(仅解码) |
示例用法
使用 Cabinet
类型读取现有的 CAB 文件
use cab;
use std::fs;
use std::io;
let cab_file = fs::File::open("path/to/cabinet.cab").unwrap();
let mut cabinet = cab::Cabinet::new(cab_file).unwrap();
// List all files in the cabinet, with file sizes and compression types:
for folder in cabinet.folder_entries() {
for file in folder.file_entries() {
println!("File {} ({} B) is compressed with {:?}",
file.name(),
file.uncompressed_size(),
folder.compression_type());
}
}
// Decompress a particular file in the cabinet and save it to disk:
let mut reader = cabinet.read_file("images/example.png").unwrap();
let mut writer = fs::File::create("out/example.png").unwrap();
io::copy(&mut reader, &mut writer).unwrap();
创建一个新的 CAB 文件稍微复杂一些。由于 CAB 文件在磁盘上的结构,库必须在开始向磁盘写入任何内容之前知道将包含在 CAB 文件中的所有文件的名称。然而,我们不想一次将所有文件的 内容 保留在内存中。因此,CAB 创建分为两个步骤:首先,创建一个 CabinetBuilder
并指定所有文件名和其他元数据,然后第二次,将每个文件的数据流式传输到 CabinetWriter
,一次一个
use cab;
use std::fs;
use std::io;
let mut cab_builder = cab::CabinetBuilder::new();
// Add a single file in its own folder:
cab_builder.add_folder(cab::CompressionType::None).add_file("img/foo.jpg");
// Add several more files, compressed together in a second folder:
{
let folder = cab_builder.add_folder(cab::CompressionType::MsZip);
folder.add_file("documents/README.txt");
folder.add_file("documents/license.txt");
// We can also specify metadata on individual files:
{
let file = folder.add_file("documents/hidden.txt");
file.set_is_hidden(true);
file.set_is_read_only(true);
}
}
// Now, we'll actually construct the cabinet file on disk:
let cab_file = fs::File::create("path/to/cabinet.cab").unwrap();
let mut cab_writer = cab_builder.build(cab_file).unwrap();
while let Some(mut writer) = cab_writer.next_file().unwrap() {
let mut reader = fs::File::open(writer.file_name()).unwrap();
io::copy(&mut reader, &mut writer).unwrap();
}
// Print the file size of the cabinet file we just created:
let mut cab_file = cab_writer.finish().unwrap();
println!("Cabinet size: {} B", cab_file.metadata().unwrap().len());
依赖项
~1.5MB
~25K SLoC