All formats

Apache Commons Compress

LanguageJava 8+
LicenseApache 2.0
Repositorygithub.com/apache/commons-compress
Documentation7z examples, SevenZFile javadoc, limitations
Depends oncommons-io, commons-lang3; XZ for Java (org.tukaani:xz) for LZMA and LZMA2
Read / writeyes / yes; reads LZMA, LZMA2, BZip2, Deflate, Deflate64, Delta, BCJ filters, AES-256; writes LZMA2 (default), BZip2, Deflate, Copy without encryption

Commons Compress is the Apache library for archive and compression formats in Java: ZIP, TAR, 7z, CPIO, AR, ARJ, DUMP and the compressors gzip, bzip2, xz, lzma, zstd, brotli and Snappy. Its 7z support is in the org.apache.commons.compress.archivers.sevenz package: SevenZFile reads, SevenZOutputFile writes.

Reading supports solid archives, compressed headers and AES-256 encrypted archives (data and headers). It doesn’t support PPMd or BCJ2, so some archives made by 7-Zip with -m0=PPMd or with default settings for .exe files (BCJ2 at high levels) can’t be read. Writing produces non-solid archives without encryption or header compression.

SevenZFile needs random access (a File, Path or SeekableByteChannel), because the 7z header is at the end of the file. It can’t read from an InputStream.

Installation#

Maven:

XML
<dependency>
  <groupId>org.apache.commons</groupId>
  <artifactId>commons-compress</artifactId>
  <version>1.28.0</version>
</dependency>
<dependency>
  <groupId>org.tukaani</groupId>
  <artifactId>xz</artifactId>
  <version>1.10</version>
</dependency>

Gradle:

implementation("org.apache.commons:commons-compress:1.28.0")
implementation("org.tukaani:xz:1.10")

Basic usage: list and extract a 7z archive#

Java
import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry;
import org.apache.commons.compress.archivers.sevenz.SevenZFile;

import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;

public class Extract7z {
    public static void main(String[] args) throws IOException {
        Path outDir = Path.of("output").toAbsolutePath().normalize();
        try (SevenZFile sevenZFile = SevenZFile.builder().setFile("archive.7z").get()) {
            SevenZArchiveEntry entry;
            while ((entry = sevenZFile.getNextEntry()) != null) {
                Path target = outDir.resolve(entry.getName()).normalize();
                if (!target.startsWith(outDir)) {
                    throw new IOException("bad entry name: " + entry.getName());  // "../" in the name
                }
                if (entry.isDirectory()) {
                    Files.createDirectories(target);
                    continue;
                }
                System.out.println(entry.getName() + "  " + entry.getSize() + " bytes");
                Files.createDirectories(target.getParent());
                try (InputStream in = sevenZFile.getInputStream(entry)) {
                    Files.copy(in, target, StandardCopyOption.REPLACE_EXISTING);
                }
            }
        }
    }
}

Reading entries in order with getNextEntry is the fast path for solid archives: each block is decompressed once.

How to list files without extracting#

Java
try (SevenZFile sevenZFile = SevenZFile.builder().setFile("archive.7z").get()) {
    for (SevenZArchiveEntry entry : sevenZFile.getEntries()) {
        System.out.printf("%s %d %s%n", entry.getName(), entry.getSize(),
            entry.getHasLastModifiedDate() ? entry.getLastModifiedDate() : "");
    }
}

How to open a password-protected 7z archive#

Java
try (SevenZFile sevenZFile = SevenZFile.builder()
        .setFile("secret.7z")
        .setPassword("secret".toCharArray())
        .get()) {
    SevenZArchiveEntry entry;
    while ((entry = sevenZFile.getNextEntry()) != null) {
        byte[] content = sevenZFile.getInputStream(entry).readAllBytes();
        // ...
    }
}

A wrong password throws PasswordRequiredException when none was given, or usually an IOException with a CRC or LZMA data error.

How to create a 7z archive#

Java
import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry;
import org.apache.commons.compress.archivers.sevenz.SevenZMethod;
import org.apache.commons.compress.archivers.sevenz.SevenZOutputFile;

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;

public class Create7z {
    public static void main(String[] args) throws IOException {
        try (SevenZOutputFile out = new SevenZOutputFile(new File("backup.7z"))) {
            out.setContentCompression(SevenZMethod.LZMA2);  // default; BZIP2, DEFLATE, COPY

            // a file from disk
            Path report = Path.of("report.pdf");
            SevenZArchiveEntry entry = out.createArchiveEntry(report, "docs/report.pdf");
            out.putArchiveEntry(entry);
            out.write(report);
            out.closeArchiveEntry();

            // bytes from memory
            byte[] data = "hello, world\n".getBytes(StandardCharsets.UTF_8);
            SevenZArchiveEntry hello = new SevenZArchiveEntry();
            hello.setName("hello.txt");
            out.putArchiveEntry(hello);
            out.write(data);
            out.closeArchiveEntry();
        }  // close() writes the header at the end
    }
}

How to read a 7z archive from a byte array#

Java
import org.apache.commons.compress.utils.SeekableInMemoryByteChannel;

byte[] bytes = Files.readAllBytes(Path.of("archive.7z"));  // or from a download
try (SevenZFile sevenZFile = SevenZFile.builder()
        .setSeekableByteChannel(new SeekableInMemoryByteChannel(bytes))
        .get()) {
    // ... getNextEntry() as above
}

Tips#