[Java] Java Zip文件压缩与解压缩

来源:互联网 发布:ubuntu是什么系统 编辑:程序博客网 时间:2024/05/17 23:18
apache有个包提供一些简单的方法来实现zip文件的压缩与解压缩http://ant.apache.org/。下载地址:org.apache.tools.zip
下载下来解压缩后,该包中的ant.jar里面提供了zip文件压缩与解压缩的功能代码。在项目中引用该类库。

以下是ZipUtil类的代码,其实现了createZipFile 和 unZip两个功能
package com.util;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.util.Enumeration;import org.apache.tools.zip.ZipEntry;import org.apache.tools.zip.ZipFile;import org.apache.tools.zip.ZipOutputStream;/*** @author mango_song* */public class ZipUtil{private  ZipUtil(){}/**  * 将文件/文件夹压缩成zip文件  *  * @param filePath  *            待压缩的文件/文件夹  * @param zipFilePath  *            生成的压缩文件 * @throws IOException   */public  static void createZipFile(String filePath,String zipFilePath) throws IOException {OutputStream fos =null;ZipOutputStream zos=null;fos=new FileOutputStream(zipFilePath);zos= new ZipOutputStream(fos);File file=new File(filePath);if(file.exists()){writeZipFile(file,zos,""); }zos.close();fos.close();}private static void writeZipFile(File file,ZipOutputStream zos,String hiberarchy) throws IOException{if(file.isDirectory()){hiberarchy +=file.getName()+"/";File[] files=file.listFiles();if(files.length==0){ZipEntry entry= new ZipEntry(hiberarchy );zos.putNextEntry(entry);}else{for(File f:files){writeZipFile(f,zos,hiberarchy);}}}else{ZipEntry entry= new ZipEntry(hiberarchy +file.getName());zos.putNextEntry(entry);InputStream in =new FileInputStream(file);byte[] buf=new byte[1024*1024];int len=0;while((len=in.read(buf))!=-1){zos.write(buf,0,len);}}}/**  * 解压缩zip文件  *  * @param sourceFileName  *            要解压缩的zip文件  * @param desDir  *            解压缩到的目录  * @throws IOException  *             压缩文件的过程中可能会抛出IO异常,请自行处理该异常。  */ public static void unZip(String sourceFileName, String desDir)         throws IOException {     // 创建压缩文件对象     ZipFile zf = new ZipFile(new File(sourceFileName));       // 获取压缩文件中的文件枚举     Enumeration<ZipEntry> en = zf.getEntries();     int length = 0;     byte[] b = new byte[2048];       // 提取压缩文件夹中的所有压缩实例对象     while (en.hasMoreElements()) {         ZipEntry ze = en.nextElement();         // System.out.println("压缩文件夹中的内容:"+ze.getName());         // System.out.println("是否是文件夹:"+ze.isDirectory());         // 创建解压缩后的文件实例对象         File file = new File(desDir + ze.getName());         // System.out.println("解压后的内容:"+f.getPath());         // System.out.println("是否是文件夹:"+f.isDirectory());         // 如果当前压缩文件中的实例对象是文件夹就在解压缩后的文件夹中创建该文件夹         if (ze.isDirectory()) {             file.mkdirs();         } else {             // 如果当前解压缩文件的父级文件夹没有创建的话,则创建好父级文件夹             if (!file.getParentFile().exists()) {                 file.getParentFile().mkdirs();             }               // 将当前文件的内容写入解压后的文件夹中。             OutputStream outputStream = new FileOutputStream(file);             InputStream inputStream = zf.getInputStream(ze);             while ((length = inputStream.read(b)) > 0)                 outputStream.write(b, 0, length);               inputStream.close();             outputStream.close();         }     }     zf.close(); }public static void main(String args[]) throws IOException{//1.压缩ZipUtil.createZipFile("c:/测试", "c:/测试.zip");//2.解压缩ZipUtil.unZip("c:/测试.zip", "c:/unzip/");}}



下面是参考文献关于zip解压缩的详细介绍:
原文:http://www.cnblogs.com/stevenhqq/archive/2011/05/19/2050771.html
最近需要用到Java的zip文件压缩与解压缩,找了一堆的资料和参考代码,没有一个能够很好的解决问题。要不就是压缩出错,要不就是压缩后的文件目录组织不正确,要不就是中文乱码,总之问题一大堆。没办法只能自己编码搞定。
java里面有个包叫java.util.zip提供zip文件压缩,但是编码的时候非常不方便。编码量太多了,通过搜索,发现apache有个包提供一些简单的方法来实现zip文件的压缩与解压缩http://ant.apache.org/。下载地址:org.apache.tools.zip
下载下来解压缩后,该包中的ant.jar里面提供了zip文件压缩与解压缩的功能代码。在项目中引用该类库。

 
要压缩成zip文件,涉及到的问题如下:
1.将要压缩的文件添加到zip文件包中。
2.组织好要压缩的文件目录与压缩后的zip文件目录一致。
3.文件名以及文件夹名中文字符编码。
4.解压缩zip文件,并将解压缩后的文件及文件夹的组织形式要与压缩前的一致。
 
在设计该类的时候,我编写了一下几个方法:
第一个zip方法,将来填入要压缩的文件或文件夹路径,然后压缩成zip文件并保存到指定位置。代码如下:
复制代码
1 /** 2 * 压缩文件或者文件夹 压缩采用gb2312编码,其它编码方式可能造成文件名与文件夹名使用中文的情况下压缩后为乱码。。。 3 * 4 * @param source 5 * 要压缩的文件或者文件夹 6 * 建议使用"c:/abc"或者"c:/abc/aaa.txt"这种形式来给定压缩路径 7 * 使用"c:\\abc" 或者"c:\\abc\\aaa.txt"这种形式来给定路径的话,可能导致出现压缩和解压缩路径意外故障。。。 8 * @param zipFileName 9 * 压缩后的zip文件名称 压缩后的目录组织与windows的zip压缩的目录组织相同。10 * 会根据压缩的目录的名称,在压缩文件夹中创建一个改名的根目录, 其它压缩的文件和文件夹都在该目录下依照原来的文件目录组织形式11 * @throws IOException12 * 压缩文件的过程中可能会抛出IO异常,请自行处理该异常。13 */14  public static void ZIP(String source, String zipFileName)15 throws IOException {16 ZipOutputStream zos = new ZipOutputStream(new File(zipFileName));17 18 // 设置压缩的时候文件名编码为gb231219 zos.setEncoding("gb2312");20 // System.out.println(zos.getEncoding());21 22 File f = new File(source);23 24 if (f.isDirectory()) {25 // 如果直接压缩文件夹26 ZIPDIR(source, zos, f.getName() + "/");// 此处使用/来表示目录,如果使用\\来表示目录的话,会导致压缩后的文件目录组织形式在解压缩的时候不能正确识别。27 } else {28 // 如果直接压缩文件29 ZIPDIR(f.getPath(), zos, new File(f.getParent()).getName() + "/");30 ZIPFile(f.getPath(), zos, new File(f.getParent()).getName() + "/"31 + f.getName());32 }33 34 zos.closeEntry();35 zos.close();36 }
复制代码
为了很好的解决中文编码问题,这里在创建ZipOutputStream 输出流的时候就指定其编码为gb2312,这样无论将来是中文的文件名和文件夹,都可以被正确的识别,不会出现乱码的情况。
特别提醒大家注意的是,文件的路径使用的斜杠最好是"/",如果用"\\"来表示路径的话,表面上看这是区分好了文件夹,其实在解压缩的时候zipfile对象就不能很好的识别其为文件夹,有可能将其识别为文件,导致解压出错。这里是个关键点!
第二个ZIPFile方法,专门将指定的文件压缩成为zip文件的方法。代码如下:
复制代码
1 /** 2 * zip 压缩单个文件。 除非有特殊需要,否则请调用ZIP方法来压缩文件! 3 * 4 * @param sourceFileName 5 * 要压缩的原文件 6 * @param zipFileName 7 * 压缩后的文件名 8 * @param zipFileName 9 * 压缩后的文件名10 * @throws IOException11 * 抛出文件异常12 */13 public static void ZIPFile(String sourceFileName, ZipOutputStream zos,14 String tager) throws IOException {15 // System.out.println(tager);16 ZipEntry ze = new ZipEntry(tager);17 zos.putNextEntry(ze);18 19 // 读取要压缩文件并将其添加到压缩文件中20 FileInputStream fis = new FileInputStream(new File(sourceFileName));21 byte[] bf = new byte[2048];22 int location = 0;23 while ((location = fis.read(bf)) != -1) {24 zos.write(bf, 0, location);25 }26 fis.close();27 }
复制代码
说明:这里写入zip文件流的时候使用了缓存,如果不使用将导致压缩的时间过长。。。(每次从硬盘读取一个字节并写入到zip文件流中,加重了硬盘的负担。。。)
经过我的机器测试,这个缓存设置1024与2048没有太多的性能差别,但是小于1024后就有较大的区别了。所以建议设置为1024或者2048。
第三个ZIPDIR方法,专门在ZIP文件中添加文件夹的方法。代码如下:
复制代码
1 /** 2 * 压缩目录。 除非有特殊需要,否则请调用ZIP方法来压缩文件! 3 * 4 * @param sourceDir 5 * 需要压缩的目录位置 6 * @param zos 7 * 压缩到的zip文件 8 * @param tager 9 * 压缩到的目标位置10 * @throws IOException11 * 压缩文件的过程中可能会抛出IO异常,请自行处理该异常。12 */13 public static void ZIPDIR(String sourceDir, ZipOutputStream zos,14 String tager) throws IOException {15 // System.out.println(tager);16 ZipEntry ze = new ZipEntry(tager);17 zos.putNextEntry(ze);18 // 提取要压缩的文件夹中的所有文件19 File f = new File(sourceDir);20 File[] flist = f.listFiles();21 if (flist != null) {22 // 如果该文件夹下有文件则提取所有的文件进行压缩23 for (File fsub : flist) {24 if (fsub.isDirectory()) {25 // 如果是目录则进行目录压缩26 ZIPDIR(fsub.getPath(), zos, tager + fsub.getName() + "/");27 } else {28 // 如果是文件,则进行文件压缩29 ZIPFile(fsub.getPath(), zos, tager + fsub.getName());30 }31 }32 }33 }
复制代码
 
说明:这里使用了递归的方式来读取要压缩的文件夹中的下级文件夹,全部将其压到zip文件中,用来组织好将来压缩好的zip文件里面的目录形式。
 
第四个UnZip方法,专门用于解压缩zip文件的方法。代码如下:
复制代码
1 /** 2 * 解压缩zip文件 3 * 4 * @param sourceFileName 5 * 要解压缩的zip文件 6 * @param desDir 7 * 解压缩到的目录 8 * @throws IOException 9 * 压缩文件的过程中可能会抛出IO异常,请自行处理该异常。10 */11 public static void UnZIP(String sourceFileName, String desDir)12 throws IOException {13 // 创建压缩文件对象14 ZipFile zf = new ZipFile(new File(sourceFileName));15 16 // 获取压缩文件中的文件枚举17 Enumeration<ZipEntry> en = zf.getEntries();18 int length = 0;19 byte[] b = new byte[2048];20 21 // 提取压缩文件夹中的所有压缩实例对象22 while (en.hasMoreElements()) {23 ZipEntry ze = en.nextElement();24 // System.out.println("压缩文件夹中的内容:"+ze.getName());25 // System.out.println("是否是文件夹:"+ze.isDirectory());26 // 创建解压缩后的文件实例对象27 File f = new File(desDir + ze.getName());28 // System.out.println("解压后的内容:"+f.getPath());29 // System.out.println("是否是文件夹:"+f.isDirectory());30 // 如果当前压缩文件中的实例对象是文件夹就在解压缩后的文件夹中创建该文件夹31 if (ze.isDirectory()) {32 f.mkdirs();33 } else {34 // 如果当前解压缩文件的父级文件夹没有创建的话,则创建好父级文件夹35 if (!f.getParentFile().exists()) {36 f.getParentFile().mkdirs();37 }38 39 // 将当前文件的内容写入解压后的文件夹中。40 OutputStream outputStream = new FileOutputStream(f);41 InputStream inputStream = zf.getInputStream(ze);42 while ((length = inputStream.read(b)) > 0)43 outputStream.write(b, 0, length);44 45 inputStream.close();46 outputStream.close();47 }48 }49 zf.close();50 }
复制代码
解压缩的过程并不复杂,读取zip文件,提取里面的每个zip实体,然后将其解压缩。
如果该zip实体是目录,则在解压到的文件夹中创建文件夹,如果是文件,则在指定的目录中创建文件。
这个zip压缩与解压缩代码基本完毕,写个代码测试一下效果:
复制代码
1 try { 2 long starTime = 0; 3 long endTime = 0; 4 5 // 测试压缩目录 6 // ZIPDIR("c:\\A", 7 // "c:\\A.zip"); 8 9 // 测试压缩单个文件10 // ZIPFile("c:\\A.txt",11 // "c:\\A.zip");12 13 System.out.println("开始压缩...");14 starTime = System.currentTimeMillis();15 ZIP("c:\\A",16 "c:\\A.zip");17 endTime = System.currentTimeMillis();18 System.out.println("压缩完毕!花费时间: " + (endTime - starTime) + " 毫秒!");19 20 System.out.println("开始解压...");21 starTime = System.currentTimeMillis();22 UnZIP("c:\\A.zip",23 "c:\\A\\");24 endTime = System.currentTimeMillis();25 System.out.println("解压完毕!花费时间: " + (endTime - starTime) + " 毫秒!");26 27 } catch (Exception ex) {28 // TODO Auto-generated catch block29 ex.printStackTrace();30 }
复制代码
原创粉丝点击