Have you ever had the requirement to compress or uncompress files or byte streams from within your java applications? This requirement seems to be a common need for me in all sorts of applications from B2B data feeds to my client applications. Within my client applications I allow users to attach files to records and I compress them to conserve space before storing them on the server. Once I compress the byte stream, I usually do one of two things. I will either store the byte stream representing the compressed file directly into a BLOB column in my database, or I will write it to a file in a common file system location.
Below I will present my simple ZipUtil java class which allows us to easily compress and uncompress files. My class consists of two convenience methods that take a byte array and call either the java.util.zip.Deflater or java.util.zip.Inflater objects to compress/decompress the byte array, and then it returns the new byte array. These java classes provide support for general purpose compression/decompression using the ZLIB compression library.
This class is not designed to create Zip files per se, but rather to just compress and uncompress byte streams. I will present the class to you below.
/**
* Copyright (c) 2002-2004 by Timothy E. Archer. All rights reserved.
*
* $Id: ZipUtil.java,v 1.1 2004/07/07 02:55:03 tima Exp $
*
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL TIMOTHY E. ARCHER BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
package com.tima.util;
import java.io.*;
import java.util.*;
import java.util.zip.*;
import java.nio.channels.*;
import java.nio.*;
import org.apache.log4j.*;
/**
* General Zip utilities/helper methods.
*
*
* @author Tim Archer 10/29/03
* @version $Revision: 1.1 $
*/
public class ZipUtil {
/**
* Compress a byte array using the java.util.zip.Deflater object
* with BEST_COMPRESSION
* and return a byte array containing the compressed bytes.
*
* @param input The byte array to compress.
* @return byte[] The compressed byte array.
* @throws Exception If an error occurs.
*/
public static byte[] compressByteArray(byte[] input) throws Exception {
//
// Create the compressor with highest level of compression
//
Deflater compressor = new Deflater();
compressor.setLevel(Deflater.BEST_COMPRESSION);
//
// Give the compressor the data to compress
//
compressor.setInput(input);
compressor.finish();
//
// Create an expandable byte array to hold the compressed data.
// You cannot use an array that's the same size as the orginal because
// there is no guarantee that the compressed data will be smaller than
// the uncompressed data.
//
ByteArrayOutputStream bos = new ByteArrayOutputStream(input.length);
//
// Compress the data
//
byte[] buf = new byte[1024];
while (!compressor.finished()) {
int count = compressor.deflate(buf);
bos.write(buf, 0, count);
}
try {
bos.close();
} catch (IOException e) {
}
//
// Get the compressed data
//
byte[] compressedData = bos.toByteArray();
return compressedData;
}
/**
* Uncompress a compressed byte array using the java.util.zip.Inflater
* object and return a byte array containing the uncompressed bytes.
*
* @param compressedData The byte array to uncompress.
* @return byte[] The uncompressed byte array.
* @throws Exception If an error occurs.
*/
public static byte[] uncompressByteArray(byte[] compressedData) throws Exception {
//
// Create the decompressor and give it the data to compress
//
Inflater decompressor = new Inflater();
decompressor.setInput(compressedData);
//
// Create an expandable byte array to hold the decompressed data
//
ByteArrayOutputStream bos = new ByteArrayOutputStream(compressedData.length);
//
// Decompress the data
//
byte[] buf = new byte[1024];
while (!decompressor.finished()) {
try {
int count = decompressor.inflate(buf);
bos.write(buf, 0, count);
} catch (DataFormatException e) {
}
}
try {
bos.close();
} catch (IOException e) {
}
//
// Get the decompressed data
//
byte[] decompressedData = bos.toByteArray();
return decompressedData;
}
/**
* Main - Main unit test procedure
* @param args Command line arguments.
*
*/
public static void main(String args[]) {
try {
System.out.println("ZipUtil starting.");
//
//Read the file into a byte array. I know, this is not the best way
//to do this, its just simple for a test
//
FileInputStream fis = new FileInputStream("c:\\temp\\test.txt");
FileChannel fc = fis.getChannel();
// fc.size returns the size of the file which backs the channel
byte[] data = new byte[(int) fc.size()];
ByteBuffer bb = ByteBuffer.wrap(data);
fc.read(bb);
System.out.println("Uncompressed Byte Array Size: "+data.length);
//Compress the byte array
byte [] compressedData = ZipUtil.compressByteArray(data);
System.out.println("Compressed Byte Array Size: "+compressedData.length);
//uncompress the byte array
byte [] uncompressedData = ZipUtil.uncompressByteArray(compressedData);
//Print out the contents of the uncompressed byte array
System.out.println("Uncompressed Data: " + new String(uncompressedData));
} catch (Exception e) {
System.err.println("An error occurred:"+e.toString());
}
}
}

del.icio.us
Digg
StumbleUpon