java实现zip压缩
生活随笔
收集整理的這篇文章主要介紹了
java实现zip压缩
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
1、工具類代碼
package com.scy.utils;import org.springframework.util.StringUtils;import java.io.*; import java.util.Arrays; import java.util.Enumeration; import java.util.List; import java.util.zip.*;/*** 提供了zip的壓縮和解壓方法*/ public class ZipUtil {/*** 文件夾壓縮成ZIP** @param srcDir 壓縮文件夾路徑* @param out 壓縮文件輸出流* @param KeepDirStructure 是否保留原來的目錄結(jié)構(gòu),true:保留目錄結(jié)構(gòu);* false:所有文件跑到壓縮包根目錄下(注意:不保留目錄結(jié)構(gòu)可能會(huì)出現(xiàn)同名文件,會(huì)壓縮失敗)* @throws RuntimeException 壓縮失敗會(huì)拋出運(yùn)行時(shí)異常*/public static void toZip(String srcDir, OutputStream out, boolean KeepDirStructure) throws RuntimeException {long start = System.currentTimeMillis();ZipOutputStream zos = null;try {zos = new ZipOutputStream(out);File sourceFile = new File(srcDir);compress(sourceFile, zos, sourceFile.getName(), KeepDirStructure);long end = System.currentTimeMillis();System.out.println("壓縮完成,耗時(shí):" + (end - start) + " ms");} catch (Exception e) {throw new RuntimeException("zip error from ZipUtils", e);} finally {if (zos != null) {try {zos.close();} catch (IOException e) {e.printStackTrace();}}}}/*** 文件列表壓縮成ZIP** @param srcFiles 需要壓縮的文件列表* @param out 壓縮文件輸出流* @throws RuntimeException 壓縮失敗會(huì)拋出運(yùn)行時(shí)異常*/public static void toZip(List<File> srcFiles, OutputStream out) throws RuntimeException {long start = System.currentTimeMillis();ZipOutputStream zos = null;try {zos = new ZipOutputStream(out);for (File srcFile : srcFiles) {byte[] buf = new byte[1024];zos.putNextEntry(new ZipEntry(srcFile.getName()));int len;FileInputStream in = new FileInputStream(srcFile);while ((len = in.read(buf)) != -1) {zos.write(buf, 0, len);}zos.closeEntry();in.close();}long end = System.currentTimeMillis();System.out.println("壓縮完成,耗時(shí):" + (end - start) + " ms");} catch (Exception e) {throw new RuntimeException("zip error from ZipUtils", e);} finally {if (zos != null) {try {zos.close();} catch (IOException e) {e.printStackTrace();}}}}/*** 遞歸壓縮方法** @param sourceFile 源文件* @param zos zip輸出流* @param name 壓縮后的名稱* @param KeepDirStructure 是否保留原來的目錄結(jié)構(gòu),true:保留目錄結(jié)構(gòu);* false:所有文件跑到壓縮包根目錄下(注意:不保留目錄結(jié)構(gòu)可能會(huì)出現(xiàn)同名文件,會(huì)壓縮失敗)* @throws Exception*/private static void compress(File sourceFile, ZipOutputStream zos, String name, boolean KeepDirStructure) throws Exception {byte[] buf = new byte[1024];if (sourceFile.isFile()) {// 向zip輸出流中添加一個(gè)zip實(shí)體,構(gòu)造器中name為zip實(shí)體的文件的名字zos.putNextEntry(new ZipEntry(name));// copy文件到zip輸出流中int len;FileInputStream in = new FileInputStream(sourceFile);while ((len = in.read(buf)) != -1) {zos.write(buf, 0, len);}// Complete the entryzos.closeEntry();in.close();} else {File[] listFiles = sourceFile.listFiles();if (listFiles == null || listFiles.length == 0) {// 需要保留原來的文件結(jié)構(gòu)時(shí),需要對(duì)空文件夾進(jìn)行處理if (KeepDirStructure) {// 空文件夾的處理zos.putNextEntry(new ZipEntry(name + "/"));// 沒有文件,不需要文件的copyzos.closeEntry();}} else {for (File file : listFiles) {// 判斷是否需要保留原來的文件結(jié)構(gòu)if (KeepDirStructure) {// 注意:file.getName()前面需要帶上父文件夾的名字加一斜杠,// 不然最后壓縮包中就不能保留原來的文件結(jié)構(gòu),即:所有文件都跑到壓縮包根目錄下了compress(file, zos, name + "/" + file.getName(), KeepDirStructure);} else {compress(file, zos, file.getName(), KeepDirStructure);}}}}}/*** 解壓縮zip包** @param zipFilePath zip文件的全路徑* @param destPath 解壓后的文件保存的路徑* @param includeZipFileName 解壓后的文件保存的路徑是否包含壓縮文件的文件名。true-包含;false-不包含*/@SuppressWarnings("unchecked")public static void unzip(String zipFilePath, String destPath, boolean includeZipFileName) throws Exception {if (StringUtils.isEmpty(zipFilePath) || StringUtils.isEmpty(destPath)) {throw new Exception();}File zipFile = new File(zipFilePath);//如果解壓后的文件保存路徑包含壓縮文件的文件名,則追加該文件名到解壓路徑if (includeZipFileName) {String fileName = zipFile.getName();if (null != fileName && !"".equals(fileName)) {fileName = fileName.substring(0, fileName.lastIndexOf("."));}destPath = destPath + File.separator + fileName + File.separator;}File destPathFile = new File(destPath);// 創(chuàng)建文件夾if (!destPathFile.exists() || !destPathFile.isDirectory()) {destPathFile.mkdirs();}//開始解壓ZipFile zip = new ZipFile(zipFile);Enumeration<ZipEntry> entries = (Enumeration<ZipEntry>) zip.entries();//循環(huán)對(duì)壓縮包里的每一個(gè)文件進(jìn)行解壓while (entries.hasMoreElements()) {ZipEntry entry = entries.nextElement();String entryName = entry.getName().replace("/", File.separator);String destFilePath = destPath + File.separator + entryName;String outPath = destFilePath.substring(0, destFilePath.lastIndexOf(File.separator));File pathFile = new File(outPath);// 創(chuàng)建文件夾if (!pathFile.exists() || !pathFile.isDirectory()) {pathFile.mkdirs();}File destFile = new File(destFilePath);// 判斷是否為文件夾if (destFile.isDirectory()) {continue;}//刪除已存在的文件/*if (destFile.exists()) {//檢測(cè)文件是否允許刪除,如果不允許刪除,將會(huì)拋出SecurityException*//*SecurityManager securityManager = new SecurityManager();securityManager.checkDelete(destFilePath);*//*//刪除已存在的目標(biāo)文件destFile.delete();}*///寫入文件BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile));InputStream inputStream = zip.getInputStream(entry);BufferedInputStream bis = new BufferedInputStream(inputStream);byte[] buffer = new byte[1024];int size = 0;while ((size = bis.read(buffer)) != -1) {bos.write(buffer, 0, size);}bos.flush();bos.close();bis.close();inputStream.close();}zip.close();}/*** 測(cè)試方法* 注意:操作時(shí)會(huì)覆蓋重名文件** @param args*/public static void main(String[] args) {try {// 1、壓縮文件夾zipDirTest();// 2、壓縮文件列表zipFileListTest();// 3、解壓測(cè)試unzipTest();} catch (Exception e) {e.printStackTrace();}}private static void unzipTest() throws Exception {String zipFilePath = "F:\\testzip.zip";String unzipFilePath = "F:\\unzip";unzip(zipFilePath, unzipFilePath, false);}private static void zipFileListTest() throws FileNotFoundException {String srcFile = "F:\\testzip\\1.txt";String destFile = "F:\\testzip\\1.zip";FileOutputStream fos = new FileOutputStream(destFile);toZip(Arrays.asList(new File(srcFile)), fos);}private static void zipDirTest() throws FileNotFoundException {String srcFileDir = "F:\\testzip";String destFile = "F:\\testzip\\testzip.zip";FileOutputStream fos = new FileOutputStream(destFile);toZip(srcFileDir, fos, true);} }2、使用CheckedOutputStream和CheckedInputStream實(shí)現(xiàn)帶驗(yàn)證的壓縮、解壓
下面例子演示如何通過CheckedOutputStream和CheckedInputStream實(shí)現(xiàn)帶驗(yàn)證的壓縮、解壓。
采用了Adler32算法,當(dāng)然大家用CRC32算法也可以。
通過FilenameFilter方法,取得workspace/你的工程目錄下的所有txt文件,但不包含子目錄下的txt文件。
用途:主要用于需要確保壓縮文件在壓縮跟解壓的無誤操作,確保完全相同。
壓縮例子代碼:
package ajava.code.javase;import java.io.*; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; import java.util.zip.CheckedOutputStream; import java.util.zip.Adler32;public class AjavaZipWithChecksum {public static void main(String[] args) {try {String target = "ajavachecksum.zip";FileOutputStream fos = new FileOutputStream(target);//使用Adler32算法創(chuàng)建CheckedOutputStream校驗(yàn)輸出流CheckedOutputStream checksum = new CheckedOutputStream(fos, new Adler32());ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(checksum));int size = 0;byte[] buffer = new byte[1024];//// Get all text files on the working folder.//通過FilenameFilter取得所有txt文件File dir = new File(".");String[] files = dir.list(new FilenameFilter() {public boolean accept(File dir, String name) {if (name.endsWith(".txt")) {return true;} else {return false;}}});//壓縮成ajavachecksum.zipfor (int i = 0; i < files.length; i++) {System.out.println("壓縮中...: " + files[i]);FileInputStream fis = new FileInputStream(files[i]);BufferedInputStream bis = new BufferedInputStream(fis, buffer.length);ZipEntry zipEntry = new ZipEntry(files[i]);zos.putNextEntry(zipEntry);while ((size = fis.read(buffer, 0, buffer.length)) > 0) {zos.write(buffer, 0, size);}zos.closeEntry();fis.close();}zos.close();System.out.println(" 校驗(yàn)碼 : " + checksum.getChecksum().getValue());} catch (IOException e) {e.printStackTrace();}} }解壓例子代碼:
package ajava.code.javase;import java.io.*; import java.util.zip.ZipInputStream; import java.util.zip.ZipEntry; import java.util.zip.CheckedInputStream; import java.util.zip.Adler32;public class AjavaUnzipWithChecksum {public static void main(String[] args) {String zipname = "ajavachecksum.zip";try {FileInputStream fis = new FileInputStream(zipname);//使用Adler32算法創(chuàng)建CheckedInputStream校驗(yàn)輸出流CheckedInputStream checksum = new CheckedInputStream(fis, new Adler32());ZipInputStream zis = new ZipInputStream(new BufferedInputStream(checksum));ZipEntry entry;//解壓ajavachecksum.zipwhile ((entry = zis.getNextEntry()) != null) {System.out.println("解壓中....: " + entry.getName());int size;byte[] buffer = new byte[2048];FileOutputStream fos = new FileOutputStream(entry.getName());BufferedOutputStream bos = new BufferedOutputStream(fos, buffer.length);while ((size = zis.read(buffer, 0, buffer.length)) != -1) {bos.write(buffer, 0, size);}bos.flush();bos.close();}zis.close();fis.close();System.out.println("校驗(yàn)碼 = " + checksum.getChecksum().getValue());} catch (IOException e) {e.printStackTrace();}} }運(yùn)行結(jié)果:
壓縮中…: ajava11.txt
壓縮中…: ajava.txt
校驗(yàn)碼: 783456913
解壓中…: ajava11.txt
解壓中…: ajava.txt
校驗(yàn)碼 = 783456913
總結(jié)
以上是生活随笔為你收集整理的java实现zip压缩的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring事务问题
- 下一篇: 李宏毅——终身学习lifelong le