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.
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.
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();
Check out the LzmaAlone.java and LzmaBench.java files in the Java/SevenZip folder of the zip file from that link you posted.
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
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();
Here are tested examples of using XZ Utils pure java library to pack and unpack XZ archives with LZMA2 compression algorithm with great ratio.
import org.tukaani.xz.*;
// CompressXz
public static void main(String[] args) throws Exception {
String from = args[0];
String to = args[1];
try (FileOutputStream fileStream = new FileOutputStream(to);
XZOutputStream xzStream = new XZOutputStream(
fileStream, new LZMA2Options(LZMA2Options.PRESET_MAX), BasicArrayCache.getInstance())) {
Files.copy(Paths.get(from), xzStream);
}
}
// DecompressXz
public static void main(String[] args) throws Exception {
String from = args[0];
String to = args[1];
try (FileInputStream fileStream = new FileInputStream(from);
XZInputStream xzStream = new XZInputStream(fileStream, BasicArrayCache.getInstance())) {
Files.copy(xzStream, Paths.get(to), StandardCopyOption.REPLACE_EXISTING);
}
}
// DecompressXzSeekable (partial)
public static void main(String[] args) throws Exception {
String from = args[0];
String to = args[1];
int offset = Integer.parseInt(args[2]);
int size = Integer.parseInt(args[3]);
try (SeekableInputStream fileStream = new SeekableFileInputStream(from);
SeekableXZInputStream xzStream = new SeekableXZInputStream(fileStream, BasicArrayCache.getInstance())) {
xzStream.seek(offset);
byte[] buf = new byte[size];
if (size != xzStream.read(buf)) {
xzStream.available(); // let it throw the last exception, if any
throw new IOException("Truncated stream");
}
Files.write(Paths.get(to), buf);
}
}