http://www.java3z.com/cwbwebhome/article/article8/81131.html
BZip2與GZip有什麼淵源,我這裏不深究。我要說的只是,這兩種算法,你在linux下都可以找到相應的操作命令。
GZip
壓縮
gzip <file> 將得到壓縮文件<file>.gz,同時刪除文件<file>
解壓縮
gzip -d <file>.gz 將得到壓縮文件<file>,同時刪除文件<file>.gz
BZip2與之相當,幾乎沒有什麼差別~~
BZip2
壓縮
bzip2 <file> 將得到壓縮文件<file>.bz2,同時刪除文件<file>
解壓縮
bzip2 -d <file>.bz2 將得到壓縮文件<file>,同時刪除文件<file>.bz2
除了命令不同外,幾乎是一樣的!
再說實現。GZIP是JDK自帶的算法實現,但BZip2則不曾享受這個待遇。 不過,強大的Apache堅決不會讓這些個在Linux下如魚得水的算法在Java世界中銷聲匿跡。Apache在Commons Compress中提供了相應的實現。同時,還包括衆所周知的tar、cpio、zip等算法實現,其中最爲豐富的當屬zip實現了!
我繼續依葫蘆畫瓢~~~
BZip2CompressorOutputStream類用於壓縮
BZip2CompressorInputStream類用於解壓縮
先說壓縮實現,BZip2CompressorOutputStream只有一個方法用於壓縮,就是帶定長的write方法。簡單調用如下文所示:
/**
* 數據壓縮
*
* @param is
* @param os
* @throws Exception
*/
public static void compress(InputStream is, OutputStream os)
throws Exception {
BZip2CompressorOutputStream gos = new BZip2CompressorOutputStream(os);
int count;
byte data[] = new byte[BUFFER];
while ((count = is.read(data, 0, BUFFER)) != -1) {
gos.write(data, 0, count);
}
gos.finish();
gos.flush();
gos.close();
}
與GZip實現有何差別?除了換掉了GZIPOutputStream沒有任何差別。
解壓縮就更不用說了,BZip2CompressorInputStream提供了一個帶定長的read方法。簡單調用如下文所示:
/**
* 數據解壓縮
*
* @param is
* @param os
* @throws Exception
*/
public static void decompress(InputStream is, OutputStream os)
throws Exception {
BZip2CompressorInputStream gis = new BZip2CompressorInputStream(is);
int count;
byte data[] = new byte[BUFFER];
while ((count = gis.read(data, 0, BUFFER)) != -1) {
os.write(data, 0, count);
}
gis.close();
}
嗯,沒什麼難度!
IT這行就是這樣,只要你肯用心,能觸類旁通,就能融會貫通!
給一個完整實現:
/**
* 2010-4-15
*/
package org.zlex.commons.compress.compress;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream;
import org.apache.commons.compress.compressors.bzip2.BZip2CompressorOutputStream;
/**
* BZip2工具
*
* @author <a href="mailto:[email protected]">樑棟</a>
* @since 1.0
*/
public abstract class BZip2Utils {
public static final int BUFFER = 1024;
public static final CharSequence EXT = ".bz2";
/**
* 數據壓縮
*
* @param data
* @return
* @throws Exception
*/
public static byte[] compress(byte[] data) throws Exception {
ByteArrayInputStream bais = new ByteArrayInputStream(data);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// 壓縮
compress(bais, baos);
byte[] output = baos.toByteArray();
baos.flush();
baos.close();
bais.close();
return output;
}
/**
* 文件壓縮
*
* @param file
* @throws Exception
*/
public static void compress(File file) throws Exception {
compress(file, true);
}
/**
* 文件壓縮
*
* @param file
* @param delete
* 是否刪除原始文件
* @throws Exception
*/
public static void compress(File file, boolean delete) throws Exception {
FileInputStream fis = new FileInputStream(file);
FileOutputStream fos = new FileOutputStream(file.getPath() + EXT);
compress(fis, fos);
fis.close();
fos.flush();
fos.close();
if (delete) {
file.delete();
}
}
/**
* 數據壓縮
*
* @param is
* @param os
* @throws Exception
*/
public static void compress(InputStream is, OutputStream os)
throws Exception {
BZip2CompressorOutputStream gos = new BZip2CompressorOutputStream(os);
int count;
byte data[] = new byte[BUFFER];
while ((count = is.read(data, 0, BUFFER)) != -1) {
gos.write(data, 0, count);
}
gos.finish();
gos.flush();
gos.close();
}
/**
* 文件壓縮
*
* @param path
* @throws Exception
*/
public static void compress(String path) throws Exception {
compress(path, true);
}
/**
* 文件壓縮
*
* @param path
* @param delete
* 是否刪除原始文件
* @throws Exception
*/
public static void compress(String path, boolean delete) throws Exception {
File file = new File(path);
compress(file, delete);
}
/**
* 數據解壓縮
*
* @param data
* @return
* @throws Exception
*/
public static byte[] decompress(byte[] data) throws Exception {
ByteArrayInputStream bais = new ByteArrayInputStream(data);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// 解壓縮
decompress(bais, baos);
data = baos.toByteArray();
baos.flush();
baos.close();
bais.close();
return data;
}
/**
* 文件解壓縮
*
* @param file
* @throws Exception
*/
public static void decompress(File file) throws Exception {
decompress(file, true);
}
/**
* 文件解壓縮
*
* @param file
* @param delete
* 是否刪除原始文件
* @throws Exception
*/
public static void decompress(File file, boolean delete) throws Exception {
FileInputStream fis = new FileInputStream(file);
FileOutputStream fos = new FileOutputStream(file.getPath().replace(EXT,
""));
decompress(fis, fos);
fis.close();
fos.flush();
fos.close();
if (delete) {
file.delete();
}
}
/**
* 數據解壓縮
*
* @param is
* @param os
* @throws Exception
*/
public static void decompress(InputStream is, OutputStream os)
throws Exception {
BZip2CompressorInputStream gis = new BZip2CompressorInputStream(is);
int count;
byte data[] = new byte[BUFFER];
while ((count = gis.read(data, 0, BUFFER)) != -1) {
os.write(data, 0, count);
}
gis.close();
}
/**
* 文件解壓縮
*
* @param path
* @throws Exception
*/
public static void decompress(String path) throws Exception {
decompress(path, true);
}
/**
* 文件解壓縮
*
* @param path
* @param delete
* 是否刪除原始文件
* @throws Exception
*/
public static void decompress(String path, boolean delete) throws Exception {
File file = new File(path);
decompress(file, delete);
}
}
對應再來個測試用例,測試用例如下所示:
/**
* 2010-4-13
*/
package org.zlex.commons.compress.compress;
import static org.junit.Assert.assertEquals;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import org.junit.Test;
/**
* BZip2
*
* @author <a href="mailto:[email protected]">樑棟</a>
* @since 1.0
*/
public class BZip2UtilsTest {
private String inputStr = "[email protected],[email protected],[email protected],[email protected], [email protected],[email protected],[email protected],[email protected],[email protected], [email protected],[email protected],[email protected],[email protected],[email protected], [email protected],[email protected],[email protected],[email protected],[email protected], [email protected],[email protected],[email protected],[email protected],zlex.snowolf@zlex. org,[email protected],[email protected],[email protected],[email protected], [email protected],[email protected]";@Testpublic final void testDataCompress() throws Exception {byte[] input = inputStr.getBytes();System.err.println("原文:\t" + inputStr);System.err.println("長度:\t" + input.length);byte[] data = BZip2Utils.compress(input);System.err.println("壓縮後:\t");System.err.println("長度:\t" + data.length);byte[] output = BZip2Utils.decompress(data);String outputStr = new String(output);System.err.println("解壓縮後:\t" + outputStr);System.err.println("長度:\t" + output.length);assertEquals(inputStr, outputStr);}@Testpublic final void testFileCompress() throws Exception {FileOutputStream fos = new FileOutputStream("d:/f.txt");fos.write(inputStr.getBytes());fos.flush();fos.close();BZip2Utils.compress("d:/f.txt");BZip2Utils.decompress("d:/f.txt.bz2");File file = new File("d:/f.txt");FileInputStream fis = new FileInputStream(file);DataInputStream dis = new DataInputStream(fis);byte[] data = new byte[(int) file.length()];dis.readFully(data);fis.close();String outputStr = new String(data);assertEquals(inputStr, outputStr);}}
雖然,兩種算法在代碼實現上幾乎沒有什麼差別,但在壓縮上想要看到效果,還真讓我費了點事!
控制檯輸出(略)
GZIP本身不需要太長的內容,經過壓縮就能體現出壓縮效果,而BZip2則需要壓縮很長的內容時,才能體現其壓縮效果,這說明BZip2更適合大數據壓縮?!