7 releases (breaking)
0.6.0 | Apr 5, 2024 |
---|---|
0.5.0 | Nov 24, 2023 |
0.4.1 | Jun 20, 2022 |
0.4.0 | May 4, 2022 |
0.1.0 | Feb 20, 2018 |
#232 in Parser implementations
78,284 downloads per month
Used in 30 crates
(9 directly)
94KB
2K
SLoC
rust-cab
A pure Rust library for reading/writing Windows cabinet (CAB) files.
Documentation: https://docs.rs/cab
License
rust-cab is made available under the MIT License.
lib.rs
:
A library for reading/writing Windows cabinet (CAB) files.
Overview
CAB is an archive file format used by Windows. A cabinet file can contain multiple compressed files, which are divided into "folders" (no relation to filesystem folders/directories); files in the same folder are compressed together, and each folder in the cabinet can potentially use a different compression scheme. The CAB file format supports multiple different compression schemes; this library can recognize all of them when reading metadata for an existing cabinet file, but currently only supports encoding/decoding some of them, as shown:
Compression | Supported |
---|---|
Uncompressed | Yes |
MSZIP (Deflate) | Yes |
Quantum | No |
LZX | Yes (decode only) |
Example usage
Use the Cabinet
type to read an existing cabinet file:
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();
Creating a new cabinet file is a little more involved. Because of how the
cabinet file is structured on disk, the library has to know the names of
all the files that will be in the cabinet up front, before it can start
writing anything to disk. However, we don't want to have to hold all the
file contents in memory at once. Therefore, cabinet creation happens
in two steps: first, create a CabinetBuilder
and specify all filenames
and other metadata, and then second, stream each file's data into a
CabinetWriter
, one at a time:
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());
Dependencies
~1.5MB
~24K SLoC