Expand description
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:
§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());
Structs§
- A structure for reading a cabinet file.
- A structure for building a new cabinet.
- A structure for writing file data into a new cabinet file.
- A structure for building a file within a new cabinet.
- An iterator over the file entries in a folder.
- Metadata about one file stored in a cabinet.
- A reader for reading decompressed data from a cabinet file.
- Allows writing data for a single file within a new cabinet.
- A structure for building a folder within a new cabinet.
- An iterator over the folder entries in a cabinet.
- Metadata about one folder in a cabinet.
Enums§
- A scheme for compressing data within the cabinet.
- The window size is not stored in the compressed data stream and must be known before decoding begins.