Java解壓縮技術的實現 GZIP ZIP BZIP2
與GZIP ZIP 不同的是BZIP2在Java中沒有實現,BZIP2的實現是Apache提供的Commons-Compress.jar來實現的
關於 Commons Compress 請移步:http://commons.apache.org/proper/commons-compress/
還是直接上代碼
package com.ljh.bzip2;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.commons.compress.compressors.CompressorException;
import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream;
import org.apache.commons.compress.compressors.bzip2.BZip2CompressorOutputStream;
/**
* @Desc: BZip2 壓縮工具(測試結果:適合較大壓縮,用法與GZIP類似)
* @author ljh
* @date 2015-4-14 上午9:39:14
*/
public class BZip2Utils {
private static final int BUFFER = 8;
public static final String EXT = ".bz2";
/**
* @Description: GZIP 數據壓縮
* @author (ljh) @date 2015-4-13 下午6:00:52
* @param data
* @return
* @throws IOException
* @return byte[]
* @throws CompressorException
*/
public static byte[] compress(byte[] data) throws IOException, CompressorException {
ByteArrayInputStream bais = new ByteArrayInputStream(data);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
compress(bais, baos);// 輸入流壓縮到輸出流
baos.flush();
baos.close();
bais.close();
return baos.toByteArray();
}
/**
* @Description: GZIP 數據壓縮
* @author (ljh) @date 2015-4-14 上午9:26:30
* @param is
* @param os
* @throws IOException
* @return void
* @throws CompressorException
*/
public static void compress(InputStream is, OutputStream os) throws IOException, CompressorException {
BZip2CompressorOutputStream bzip2OS = new BZip2CompressorOutputStream(os, 8);
// CompressorOutputStream bzip2OS = new CompressorStreamFactory().createCompressorOutputStream(CompressorStreamFactory.BZIP2, os);
int count;
byte data[] = new byte[BUFFER];
while ((count = is.read(data, 0, data.length)) != -1) {
bzip2OS.write(data, 0, count);
}
bzip2OS.finish();
bzip2OS.flush();
bzip2OS.close();
}
/**
* @Description: GZIP 數據解壓縮
* @author (ljh) @date 2015-4-13 下午6:00:42
* @param data
* @return
* @throws IOException
* @return byte[]
*/
public static byte[] uncompress(byte[] data) throws IOException {
ByteArrayInputStream bais = new ByteArrayInputStream(data);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
uncompress(bais, baos);
bais.close();
return baos.toByteArray();
}
/**
* @Description: GZIP 數據解壓縮
* @author (ljh) @date 2015-4-14 上午9:26:51
* @param is
* @param os
* @throws IOException
* @return void
*/
private static void uncompress(InputStream is, OutputStream os) throws IOException {
BZip2CompressorInputStream bzip2IS = new BZip2CompressorInputStream(is);
int count;
byte data[] = new byte[BUFFER];
while ((count = bzip2IS.read(data, 0, data.length)) != -1) {
os.write(data, 0, count);
}
os.flush();
os.close();
bzip2IS.close();
}
/**
* @Description: 文件壓縮
* @author (ljh) @date 2015-4-14 上午9:28:46
* @param file
* @throws Exception
* @return void
* @throws CompressorException
*/
public static void compress(File file) throws IOException, CompressorException {
compress(file, true);
}
/**
* @Description: 文件壓縮
* @author (ljh) @date 2015-4-14 上午9:29:21
* @param file
* @param delete
* 是否刪除源文件
* @throws Exception
* @return void
* @throws IOException
* @throws CompressorException
*/
public static void compress(File file, boolean delete) throws IOException, CompressorException {
if (!file.exists()) {
// 文件不存在
}
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();
}
}
/**
* @Description: 文件壓縮
* @author (ljh) @date 2015-4-14 上午9:32:52
* @param path
* 源文件路徑
* @throws Exception
* @return void
* @throws CompressorException
*/
public static void compress(String path) throws IOException, CompressorException {
compress(path, true);
}
/**
* @Description: 文件壓縮
* @author (ljh) @date 2015-4-14 上午9:33:18
* @param path
* 源文件路徑
* @param delete
* 是否刪除源文件
* @throws Exception
* @return void
* @throws IOException
* @throws CompressorException
*/
public static void compress(String path, boolean delete) throws IOException, CompressorException {
File file = new File(path);
compress(file, delete);
}
/**
* @Description: 文件解壓縮
* @author (ljh) @date 2015-4-14 上午9:35:03
* @param file
* @throws Exception
* @return void
*/
public static void uncompress(File file) throws IOException {
uncompress(file, true);
}
/**
* @Description: 文件解壓縮
* @author (ljh) @date 2015-4-14 上午9:35:44
* @param file
* @param delete
* 是否刪除源文件
* @throws Exception
* @return void
* @throws IOException
*/
public static void uncompress(File file, boolean delete) throws IOException {
if (!file.exists()) {
// 文件不存在
}
FileInputStream fis = new FileInputStream(file);
FileOutputStream fos = new FileOutputStream(file.getPath().replace(EXT, ""));
uncompress(fis, fos);
fis.close();
fos.flush();
fos.close();
if (delete) {
file.delete();
}
}
/**
* @Description: 文件解壓縮
* @author (ljh) @date 2015-4-14 上午9:37:48
* @param path
* @throws Exception
* @return void
*/
public static void uncompress(String path) throws IOException {
uncompress(path, true);
}
/**
* @Description: 文件解壓縮
* @author (ljh) @date 2015-4-14 上午9:38:03
* @param path
* @param delete
* 是否刪除源文件
* @throws Exception
* @return void
*/
public static void uncompress(String path, boolean delete) throws IOException {
File file = new File(path);
uncompress(file, delete);
}
/**
* Tips:
* Commons Compress不僅支持BZip2算法實現,同時也支持GZip算法實現。
* 對於GZip算法實現,與Java原生實現基本上沒有什麼差別。其源代碼分析,僅僅是做了簡單的包裝。
* 不過有必要提及的一點是,Commons Compress爲壓縮(GZip和BZip2)構建了壓縮算法工廠類CompressorStreamFactory。
* 通過這個類可以方便的構建GZip和BZip2的輸入輸出流,關鍵字分別爲“gz”和“bzip2”。
*/
}
測試代碼:
@org.junit.Test
public final void testBZIP2() throws IOException, CompressorException {
byte[] bytes = "阿萊克斯大家噶拉卡死機的個啊了的卡死機格拉卡死機的了感覺打開上嶴地溝阿薩德gas的歌撒的歌第三個滴答滴答滴答滴答滴答滴答滴答".getBytes();
// 對bytes壓縮,驗證一下壓縮後的效果對比
System.out.println("壓縮前:");
System.out.println(bytes.length);
for (byte b : bytes) {
System.out.print(b + " ");
}
System.out.println();
System.out.println("壓縮後:");
byte[] bytes2 = BZip2Utils.compress(bytes);
System.out.println(bytes2.length);
for (byte b : bytes2) {
System.out.print(b + " ");
}
System.out.println();
System.out.println("解壓縮後:");
byte[] byte22 = BZip2Utils.uncompress(bytes2);
System.out.println(byte22.length);
for (byte b : byte22) {
System.out.print(b+" ");
}
//壓縮時間較長,測試壓縮12305KB文件用時17.203s,壓縮後大小383KB
// BZip2Utils.compress("F:\\Activity_win9.bmp", false);
//解壓用時4.667s
BZip2Utils.uncompress("F:\\Activity_win9.bmp.bz2" ,false);//解壓縮後與源文件相同
//要壓縮文件夾請參考ZIPUtils自行實現
}
Commons
Compress不僅支持BZip2算法實現,同時也支持GZip算法實現。對於GZip算法實現,與Java原生實現基本上沒有什麼差別。其源代碼分析,僅僅是做了簡單的包裝。
不過有必要提及的一點是,Commons Compress爲壓縮(GZip和BZip2)構建了壓縮算法工廠類CompressorStreamFactory。通過這個類可以方便的構建GZip和BZip2的輸入輸出流,關鍵字分別爲“gz”和“bzip2”。
GZip
// GzipCompressorInputStream
CompressorInputStream gzipIn = new CompressorStreamFactory().createCompressorInputStream("gz", is);
// GzipCompressorOutputStream
CompressorOutputStream gzipOut = new CompressorStreamFactory().createCompressorOutputStream("gz", os);
BZip2
// BZip2CompressorInputStream
CompressorInputStream bzip2In = new CompressorStreamFactory().createCompressorInputStream("bzip2", is);
// BZip2CompressorOutputStream
CompressorOutputStream bzip2Out = new CompressorStreamFactory().createCompressorOutputStream("bzip2", os);
GZip和BZip2在算法實現步驟上基本上沒有什麼差別,如果有必要統一,可按上述代碼實現!