Table of Contents
The bzip2 compression method was developed by Julian Seward in the late nineties. See the Wikipedia article on bzip2 and the bzip2 home page.
At4J provides a Java implementation of bzip2. Data is compressed with the BZip2OutputStream and decompressed with the BZip2InputStream.
Since bzip2 compression is a CPU-intensive task, the BZip2OutputStream supports using several, parallel compression threads. An individual BZip2OutputStream may be told how many threads that it can use, or several output streams may share a set of threads through a BZip2EncoderExecutorService.
The following example shows how data is written to a bzip2 output stream that writes to a file, and then read again from the file and decompressed.
Example 4.1. Compressing and decompressing with bzip2
// Data will be compressed to the File f String toCompress = "Compress me!"; OutputStream os = new FileOutputStream(f); try { // Use the default compression settings (maximum compression) OutputStream bzos = new BZip2OutputStream(os); try { bzos.write(toCompress.getBytes()); } finally { bzos.close(); } } finally { // Calling close here may mean that close will be called several times on the // same stream. That is safe. os.close(); } // Read the compressed data InputStream is = new FileInputStream(f); try { InputStream bzis = new BZip2InputStream(is); try { // Use the EntityFS StreamUtil utility to make our job easier. // This will print "Compress me!" System.out.println( new String( StreamUtil.readStreamFully(bzis, 32))); } finally { bzis.close(); } } finally { // Calling close here may mean that close will be called several times on the // same stream. That is safe. is.close(); }
Next example shows how a set of encoder threads is shared between two bzip2 streams.
Example 4.2. Compressing and decompressing with bzip2 using several encoder threads
// Data will be compressed to the File:s f1 and f2 String toCompress1 = "Compress me!"; String toCompress2 = "Compress me too!"; // Create a BZip2EncoderExecutorService with four threads. BZip2EncoderExecutorService executor = BZip2OutputStream.createExecutorService(4); // A settings object containing the executor service BZip2OutputStreamSettings settings = new BZip2OutputStreamSettings(). setExecutorService(executor); try { OutputStream bzos1 = new BZip2OutputStream( new FileOutputStream(f1), settings); try { OutputStream bzos2 = new BZip2OutputStream( new FileOutputStream(f2), settings); try { bzos1.write(toCompress1.getBytes()); bzos2.write(toCompress2.getBytes()); } finally { bzos2.close(); } } finally { bzos1.close(); } } finally { // Shut down the executor service executor.shutdown(); } // Read the compressed data InputStream bzis = new BZip2InputStream(new FileInputStream(f1)); try { // Use the EntityFS StreamUtil utility to make our job easier. // This will print "Compress me!" System.out.println( new String( StreamUtil.readStreamFully(bzis, 32))); } finally { bzis.close(); } bzis = new BZip2InputStream(new FileInputStream(f2)); try { // Use the EntityFS StreamUtil utility to make our job easier. // This will print "Compress me too!" System.out.println( new String( StreamUtil.readStreamFully(bzis, 32))); } finally { bzis.close(); }
At4J also bundles the bzip2 library from the Apache Commons Compress site project. It provides the BZip2CompressorInputStream for reading compressed data and the BZip2CompressorOutputStream for writing compressed data.
Note that the available
method of the
BZip2CompressorInputStream always
returns 0
.
The BZip2ReadableFile and BZip2WritableFile objects can transparently bzip2 decompress or compress data that is read from or written to a file. They implement the ReadableFile and the WritableFile interfaces respectively and can be passed to all methods that use those interfaces.
The next example does the same as the example above, except that it uses the BZip2ReadableFile and BZip2WritableFile classes.
Example 4.3. Compressing and decompressing with bzip2 using At4J readable and writable bzip2 files
// Data will be compressed to the File f String toCompress = "Compress me!"; // Wrap the File in a ReadWritableFileAdapter to make it a // ReadWritableFile ReadWritableFile fa = new ReadWritableFileAdapter(f); // Write the data using the EntityFS utility class Files and a // BZip2WritableFile. Use maximum compression (9). BZip2WritableFileSettings writeSettings = new BZip2WritableFileSettings(). setBlockSize(9); Files.writeText(new BZip2WritableFile(fa, writeSettings), toCompress); // Read the data, again using Files. The data is read from a // BZip2ReadableFile. // This will print out "Compress me!" System.out.println( Files.readTextFile( new BZip2ReadableFile(fa)));