Create 7z File - Java Example - LZMA Compression

In this tutorial, we will discuss how to create a 7z archive file in Java with an example program. We will use LZMA as the compression method for 7z file that provides a very high compression ratio when compared with ZIP or RAR formats. LZMA stands for Lempel-Ziv-Markov chain algorithm which is a popular for providing lossless data compression. You can download the source files for this compression from the following link.Compile the source code and have a JAR file, which we will make use of in this example.

A step by step code that explains creating a 7z file using LZMA compression is provided below:

Step -1 : Accept Input Files for Compression


In this step, we create a BufferedInputStream object that can accept the input file that needs to be archived. 
/* Read the input file to be compressed */
File inputToCompress = new File("trace.log");
BufferedInputStream inStream  = new BufferedInputStream(new java.io.FileInputStream(inputToCompress));

Step-2: Create Output Archive File


We create a BufferedOutputStream object in this step using which we can write the archived file back to the disk. This file should have an extension of .7z
/* Create output file 7z File */
File compressedOutput = new File("test.7z");
BufferedOutputStream outStream = new BufferedOutputStream(new java.io.FileOutputStream(compressedOutput));

Step-3: Create LZMA Encoder Object / Set Encoder Properties


Here, we create an object of type Sevenzip.compression.LZMA.Encoder and specify the following values;

  • Algorithm to be used – LZMA
  • Dictionary Size – 8 MB

There are a few other encoder properties as shown below which are the defaults for LZMA compression. You can play around with the values to see which one fits for you. Otherwise, leave it with the defaults. We also write all these encoder properties to the outputstream header at this step. (this is required for proper decompression of data)
/* Create LZMA Encoder Object / Write Header Information */
Encoder encoder = new Encoder();
encoder.SetAlgorithm(2);
encoder.SetDictionarySize(8388608);
encoder.SetNumFastBytes(128);
encoder.SetMatchFinder(1);
encoder.SetLcLpPb(3,0,2);
encoder.SetEndMarkerMode(false);
encoder.WriteCoderProperties(outStream);

Step-4:  Write 7z File Header


At this point, we are ready to write the header information for the compressed 7z file. You can know more about this if you search for LZMA header information on the internet. For now, it would be sufficient to know that you have to add the following lines of code below to set the header properties.
long fileSize;
fileSize = inputToCompress.length();
for (int i = 0; i < 8; i++)                                     
{
        outStream.write((int)(fileSize >>> (8 * i)) & 0xFF);
}                               

Step-5: Write LZMA Compressed Data to File


This is the final step and we invoke the code method in the Encoder class passing the input stream and output stream object. This will write the compressed data information into the file. Finally, we close and flush the input / output streams. At the end of this step you get a compressed 7z file using LZMA.
/* Write Compressed Data to File */     
encoder.Code(inStream, outStream, -1, -1, null);
/* Close Output Streams*/
outStream.flush();
outStream.close();
inStream.close();

Full Working Code – 7z File Compression in Java Using LZMA


The complete Java code for this tutorial is provided below. Give a try and post a comment if you are stuck.
import java.io.*;
import SevenZip.Compression.LZMA.*;
public class CompressLZMA
{
public static void main(String[] args) throws Exception
{
/* Read the input file to be compressed */
File inputToCompress = new File("trace.log");
BufferedInputStream inStream  = new BufferedInputStream(new java.io.FileInputStream(inputToCompress));
/* Create output file 7z File */
File compressedOutput = new File("test.7z");
BufferedOutputStream outStream = new BufferedOutputStream(new java.io.FileOutputStream(compressedOutput));
/* Create LZMA Encoder Object / Write Header Information */
Encoder encoder = new Encoder();
encoder.SetAlgorithm(2);
encoder.SetDictionarySize(8388608);
encoder.SetNumFastBytes(128);
encoder.SetMatchFinder(1);
encoder.SetLcLpPb(3,0,2);
encoder.SetEndMarkerMode(false);
encoder.WriteCoderProperties(outStream);
long fileSize;
fileSize = inputToCompress.length();
for (int i = 0; i < 8; i++)                                     
{
        outStream.write((int)(fileSize >>> (8 * i)) & 0xFF);
}                               
/* Write Compressed Data to File */     
encoder.Code(inStream, outStream, -1, -1, null);
/* Close Output Streams*/
outStream.flush();
outStream.close();
inStream.close();
}
}

6 comments:

  1. hello, great example, but a have a question about to inStream and outStream, how to know the progress to the compress file?

    ReplyDelete
  2. Is there any possibility to add password to 7zip file with LZMA?

    ReplyDelete
  3. Hi, Is there a response for the query? Is it possible to add a password to a 7zip file using LZMA?

    Can you pls advice?

    ReplyDelete
  4. Hi YellowRose, thanks a lot!!!
    It helps me.

    ReplyDelete
  5. Hi how to add the import "SevenZip.Compression.LZMA.*;" class

    ReplyDelete
  6. Hi I am not getting the error resolution for "Encoder cannot be resolved into a type"

    ReplyDelete