標籤:java壓縮 解壓縮 bzip2 zip gzip
Java解壓縮技術的實現 GZIP ZIP BZIP2系列實現
沒啥好說的,都是些檔案操作,直接貼代碼
package com.ljh.zip;import java.io.BufferedInputStream;import java.io.BufferedOutputStream;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.util.zip.CRC32;import java.util.zip.CheckedInputStream;import java.util.zip.CheckedOutputStream;import java.util.zip.ZipEntry;import java.util.zip.ZipInputStream;import java.util.zip.ZipOutputStream;/** * @Desc: ZIP 壓縮公用程式(檔案壓縮建議使用,支援檔案夾解壓縮) * ZIP可用於socket通訊端流資料壓縮(實現方式類似) * @author ljh * @date 2015-4-14 上午9:39:14 */public class ZipUtils {private static final int BUFFER = 1024;private static final String EXT = ".zip";private static final String BASE_DIR = "";private static final String PATH = "/"; // 符號"/"用來作為ZIP壓縮檔內部的目錄標識判斷符[因為ZipEntry.isDirectory()方法內部是以'/'來作為目錄標識符的]/** * @Description: ZIP 資料壓縮 * @author (ljh) @date 2015-4-13 下午6:00:52 * @param data * @return * @throws IOException * @return byte[] */public static byte[] compressData(byte[] data) throws IOException {ByteArrayOutputStream baos = new ByteArrayOutputStream();ZipOutputStream zipOS = new ZipOutputStream(baos);ZipEntry entry = new ZipEntry("zip");entry.setSize(data.length);zipOS.putNextEntry(entry);zipOS.write(data);zipOS.closeEntry();zipOS.close();baos.close();return baos.toByteArray();}/** * @Description: ZIP 資料解壓縮 * @author (ljh) @date 2015-4-13 下午6:00:42 * @param bytes * @return * @throws IOException * @return byte[] */public static byte[] uncompressData(byte[] data) throws IOException {ByteArrayInputStream bais = new ByteArrayInputStream(data);ZipInputStream zipIS = new ZipInputStream(bais);byte[] bytes = null;while (zipIS.getNextEntry() != null) {byte[] buf = new byte[BUFFER];int count;ByteArrayOutputStream baos = new ByteArrayOutputStream(BUFFER);while ((count = zipIS.read(buf, 0, buf.length)) != -1) {baos.write(buf, 0, count);}bytes = baos.toByteArray();baos.flush();baos.close();}zipIS.close();bais.close();return bytes;}/** * @Description: 檔案壓縮 * @author (ljh) @date 2015-4-14 上午9:32:52 * @param path * 源檔案路徑 * @throws IOException * @return void */public static void compress(String srcPath) throws IOException {compress(new File(srcPath));}public static void compress(File srcFile) throws IOException {compress(srcFile, srcFile.getPath() + EXT);}public static void compress(String srcPath, String destPath) throws IOException {compress(new File(srcPath), new File(destPath));}public static void compress(File srcFile, String destPath) throws IOException{compress(srcFile, new File(destPath));}/** * @Description: 開始檔案壓縮 * @author (ljh) @date 2015-4-14 上午10:54:06 * @param srcFile * @param destFile * @throws IOException * @return void */public static void compress(File srcFile, File destFile) throws IOException {CheckedOutputStream cos = new CheckedOutputStream(new FileOutputStream(destFile), new CRC32());// 對輸出檔案做CRC32校正ZipOutputStream zipOS = new ZipOutputStream(cos);compress(srcFile, zipOS, BASE_DIR);zipOS.flush();zipOS.close();cos.close();}/** * @Description: ZIP 檔案/目錄 * @author (ljh) @date 2015-4-14 下午12:41:33 * @param srcFile 源檔案/目錄 * @param zipOS 輸出資料流 * @param basePath * @throws IOException * @return void */public static void compress(File srcFile, ZipOutputStream zipOS, String basePath) throws IOException {if (srcFile.isDirectory()) {compressDir(srcFile, zipOS, basePath);} else {compressFile(srcFile, zipOS, basePath);}}/** * @Description: ZIP 檔案壓縮 * @author (ljh) @date 2015-4-14 上午10:36:56 * @param file * @param zipOS * @throws IOException * @return void */private static void compressFile(File file, ZipOutputStream zipOS, String basePath) throws IOException {/** * 壓縮包內檔案名稱定義 ,如果有多級目錄,那麼這裡就需要給出包含目錄的檔案名稱 ,如果用WinRAR開啟壓縮包,中文名將顯示為亂碼 */ZipEntry entry = new ZipEntry(basePath + file.getName());zipOS.putNextEntry(entry);BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));int count;byte[] buf = new byte[BUFFER];while ((count = bis.read(buf, 0, buf.length)) != -1) {zipOS.write(buf, 0, count);}bis.close();zipOS.closeEntry();}/** * @Description: 目錄壓縮 * @author (ljh) @date 2015-4-14 下午12:40:49 * @param dirFile * @param zipOS * @param basePath * @throws IOException * @return void */private static void compressDir(File dirFile, ZipOutputStream zipOS, String basePath) throws IOException {File[] files = dirFile.listFiles();// 構建空目錄if (files.length < 1) {// 空目錄ZipEntry entry = new ZipEntry(basePath + dirFile.getName() + PATH);zipOS.putNextEntry(entry);zipOS.closeEntry();}for (File file : files) {compress(file, zipOS, basePath + dirFile.getName() + PATH); // 遞迴壓縮}}//---------------------------------------------------------------/** * @Description: ZIP檔案解壓縮 * @author (ljh) @date 2015-4-14 下午12:46:25 * @param srcPath * @throws IOException * @return void */public static void uncompress(String srcPath) throws IOException {uncompress(new File(srcPath));}public static void uncompress(File srcFile) throws IOException {uncompress(srcFile, srcFile.getParent());}public static void uncompress(String srcPath, String destPath) throws IOException {uncompress(new File(srcPath), destPath);}public static void uncompress(File srcFile, String destPath) throws IOException {uncompress(srcFile, new File(destPath));}/** * @Description: 開始ZIP檔案解壓縮 * @author (ljh) @date 2015-4-14 下午12:47:00 * @param srcFile * @param destFile * @throws IOException * @return void */public static void uncompress(File srcFile, File destFile) throws IOException {CheckedInputStream cis = new CheckedInputStream(new FileInputStream(srcFile), new CRC32());ZipInputStream zipIS = new ZipInputStream(cis);uncompress(zipIS, destFile);zipIS.close();cis.close();}private static void uncompress(ZipInputStream zipIS, File destFile) throws IOException {ZipEntry entry = null;while ((entry = zipIS.getNextEntry()) != null) {String dir = destFile.getPath() + File.separator + entry.getName();File dirFile = new File(dir);fileProber(dirFile);//遞迴建立dirFile父目錄if (entry.isDirectory()) {dirFile.mkdirs();} else {uncompressFile(zipIS, dirFile);}zipIS.closeEntry();}}/** * @Description: 當父目錄不存在時,建立目錄 * @author (ljh) @date 2015-4-14 下午12:54:25 * @param dirFile * @return void */private static void fileProber(File dirFile) {File parentFile = dirFile.getParentFile();if (!parentFile.exists()) {fileProber(parentFile);//遞迴尋找上級目錄並遞迴建立parentFile.mkdir();}}/** * 檔案解壓縮 * @throws IOException */private static void uncompressFile(ZipInputStream zipIS, File destFile) throws IOException {BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile));int count;byte buf[] = new byte[BUFFER];while ((count = zipIS.read(buf, 0, buf.length)) != -1) {bos.write(buf, 0, count);}bos.close();}// --------------------------------------------}
測試方法:
/** * @Description: 被壓縮資料較大才比較明顯[測試發現中文byte位元組大於200的時候才有明顯的壓縮,英文150才明顯] * @author (ljh) @date 2015-4-14 上午11:33:13 * @throws IOException * @return void *///@org.junit.Testprivate static void testZIP() throws IOException {byte[] bytes = "啊了簡單概括啦啦as了的價格了看灑落的空間關了撒嬌g9w9eijgslkj是肯德基了感覺是肯德基斤斤計較斤斤計較斤斤計較斤斤計較斤斤計較斤斤計較死死死死死死死死死死死死啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦".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 = ZipUtils.compressData(bytes);System.out.println(bytes2.length);for (byte b : bytes2) {System.out.print(b + " ");}System.out.println();System.out.println("解壓縮後:");byte[] byte22 = ZipUtils.uncompressData(bytes2);System.out.println(byte22.length);for (byte b : byte22) {System.out.print(b+" ");}System.out.println();// ZipUtils.compress("F:\\test\\test1");//ZipUtils.uncompress("F:\\test\\test1.zip");//要壓縮檔夾請參考ZIPUtils自行實現}
點我下載相關源碼
Java解壓縮技術(一)ZIP壓縮-解壓縮