How to use LZMA SDK to compress/decompress in Java

40,585

Solution 1

Short answer: don't

The 7zip sdk is old and unmaintained and it's just a JNI wrapper around the C++ library. A pure Java implementation on a modern JVM (1.7+) is as fast as a C++ one and has less dependecies and portability issues.

Have a look at http://tukaani.org/xz/java.html

XZ is a file format based on LZMA2 (an improved version of LZMA)

The guys that invented the XZ format build a pure java implementation of the XZ archive compression / extraction algorithms

The XZ file format is designed to store 1 file only. Thus you need to zip/tar the source folder(s) into a single uncompressed file first.

Using the java library is as easy as this:

FileInputStream inFile = new FileInputStream("src.tar");
FileOutputStream outfile = new FileOutputStream("src.tar.xz");

LZMA2Options options = new LZMA2Options();

options.setPreset(7); // play with this number: 6 is default but 7 works better for mid sized archives ( > 8mb)

XZOutputStream out = new XZOutputStream(outfile, options);

byte[] buf = new byte[8192];
int size;
while ((size = inFile.read(buf)) != -1)
   out.write(buf, 0, size);

out.finish();

Solution 2

Check out the LzmaAlone.java and LzmaBench.java files in the Java/SevenZip folder of the zip file from that link you posted.

Solution 3

Use J7Zip. Its a java port of the LZMA SDK. You find it here:

http://sourceforge.net/projects/p7zip/files/J7Zip/

alternative

Use the lzmajio.jar with LzmaInputStream and LzmaOutputStream classes

you find it on github:

http://github.com/league/lzmajio/downloads

Solution 4

You can use this library instead. It is "outdated" but still works fine.

Maven dependency

<dependency>
    <groupId>com.github.jponge</groupId>
    <artifactId>lzma-java</artifactId>
    <version>1.2</version>
</dependency>

Utility class

import lzma.sdk.lzma.Decoder;
import lzma.streams.LzmaInputStream;
import lzma.streams.LzmaOutputStream;
import org.apache.commons.compress.utils.IOUtils;

import java.io.*;
import java.nio.file.Path;

public class LzmaCompressor
{
    private Path rawFilePath;
    private Path compressedFilePath;

    public LzmaCompressor(Path rawFilePath, Path compressedFilePath)
    {
        this.rawFilePath = rawFilePath;
        this.compressedFilePath = compressedFilePath;
    }

    public void compress() throws IOException
    {
        try (LzmaOutputStream outputStream = new LzmaOutputStream.Builder(
                new BufferedOutputStream(new FileOutputStream(compressedFilePath.toFile())))
                .useMaximalDictionarySize()
                .useMaximalFastBytes()
                .build();
             InputStream inputStream = new BufferedInputStream(new FileInputStream(rawFilePath.toFile())))
        {
            IOUtils.copy(inputStream, outputStream);
        }
    }

    public void decompress() throws IOException
    {
        try (LzmaInputStream inputStream = new LzmaInputStream(
                new BufferedInputStream(new FileInputStream(compressedFilePath.toFile())),
                new Decoder());
             OutputStream outputStream = new BufferedOutputStream(
                     new FileOutputStream(rawFilePath.toFile())))
        {
            IOUtils.copy(inputStream, outputStream);
        }
    }
}

Firstly you have to create a file with content to start compressing. You can use this website to generate random text.

Example compression and decompression

Path rawFile = Paths.get("raw.txt");
Path compressedFile = Paths.get("compressed.lzma");

LzmaCompressor lzmaCompressor = new LzmaCompressor(rawFile, compressedFile);
lzmaCompressor.compress();
lzmaCompressor.decompress();
Share:
40,585
lamwaiman1988
Author by

lamwaiman1988

Updated on July 15, 2020

Comments

  • lamwaiman1988
    lamwaiman1988 almost 4 years

    http://www.7-zip.org/sdk.html This site provide a LZMA SDK for compress/decompress files, I would like to give it a shot but I am lost.

    Anyone got experience on this? Or a tutorial? Thanks.

  • lamwaiman1988
    lamwaiman1988 about 13 years
    I don't understand, shouldn't they made a javadoc about it?
  • Eve Freeman
    Eve Freeman over 12 years
    Yes, they should have made some documentation (or a javadoc), but sometimes you have to look at the example code, which is what I directed you to.
  • Anubian Noob
    Anubian Noob over 9 years
    Can you explain your short answer?
  • Stefano Fratini
    Stefano Fratini over 9 years
    It's a rather old answer and the library I suggested may have been superseded by something newer/better. The gist of it is that the 7zip sdk is old and unmaintained and it's just a JNI wrapper around the C++ library. A pure Java implementation on a modern JVM (1.7+) is as fast as a C++ one and has less dependecies and portability issues. Just my 2 cents.
  • Quark
    Quark almost 8 years
    You are right on Sun/Oracle JVM it's as fast as C++. Unfortunately on Android this type of operation is still 5x - 10x slower (even on Android 6 with ART). It's frustrating.
  • Vadzim
    Vadzim about 6 years
    More examples with this library in my answer: stackoverflow.com/a/49454898/603516