- Java 99.9%
- C 0.1%
| .forgejo/workflows | ci: Fix release pipeline | |
| .idea | feat: Improved Cab Extractor | |
| .mvn/wrapper | chore: Add maven wrapper | |
| docu | docs: Add MS Docs for LZX compression | |
| src | test: Add more tests | |
| test | fix: Add remaining structures | |
| .gitignore | Initial commit | |
| jitpack.yml | build: Change version to v0.1.0-beta2 | |
| LICENSE | docs: Add email to name | |
| mvnw | chore: Add maven wrapper | |
| mvnw.cmd | chore: Add maven wrapper | |
| pom.xml | build: Increase version | |
| README.md | docs: Update readme | |
🗄️ cab4j - Cabinet Files in pure Java
A Java library for creating and reading cabinet files (*.cab) with Java using NIO ByteBuffer.
It was created using the official Microsoft CAB Documentation and has almost no dependencies.
✨ Features
- Checksum supported
- makes only use of Java NIO2 ByteBuffers
- Uncompressed, MSZIP, Quantum/LZX compression support
- Recursive directory packing with subfolder support
- Splitting archives into multiple cabinets
- Java 8+ compatible
📃 Testing and official docs
- Test files are located in
test/(sample sources from the spec indocu/). - Build and run tests with JDK 11+:
./mvnw -B -ntp verify.
Extractor API
The extractor implementation lives under de.morihofi.cab4j.extract. Use the
static methods on CabExtractor:
// In-memoryMap<String,ByteBuffer>files=CabExtractor.extract(cabBuffer);// With attributesMap<String,CabExtractor.FileData>meta=CabExtractor.extractWithAttributes(cabBuffer);// Streaming to a directoryCabExtractor.extractToDirectory(channel,outputDir);Exceptions
Common runtime exceptions are under de.morihofi.cab4j.exceptions:
CabFormatException(invalid/unsupported format),CabChecksumMismatchException(CFDATA checksum mismatch),CabDecompressionException(codec errors),CabDuplicateFileException,CabTooManyFilesOrFolderException,CabFileTooLargeException.
File attributes
CabArchive.addFile(Path) automatically records DOS file attributes like read-only or hidden when available. You can also specify attributes manually using
archive.addFile("name.txt",buffer,CfFile.ATTRIB_READONLY|CfFile.ATTRIB_HIDDEN);Use CabExtractor.extractWithAttributes to retrieve these attributes or
extractToDirectory to restore them on disk.
Directory packing
You can add entire directory trees using CabArchive.addDirectory(Path). Relative
paths are preserved inside the cabinet. When building large archives you can
split the output into multiple cabinets using CabGenerator:
CabArchivearchive=newCabArchive();archive.addDirectory(Paths.get("assets"));CabGeneratorgenerator=newCabGenerator(archive);List<ByteBuffer>cabs=generator.createCabinetSet(1_000_000);// split after 1 MBFile timestamps
CabArchive.addFile(Path) also preserves the last modified time of the source
file. When extracting with extractWithAttributes the returned
ExtractedFile contains this timestamp and extractToDirectory restores it on
disk. The time format follows the same semantics as the Java ZIP API.