鸣谢:http://blog.csdn.net/kalision/article/details/7864372
强力推荐解压:http://blog.csdn.net/smile725775/article/details/8223134
1.引言
之前在 压缩与解压1—字符串的压缩与解压(http://www.cnblogs.com/java-pan/archive/2012/05/12/gzip1.html)
中介绍过对字符串的压缩和解压,这个解压和解决用在系统之间大数据传输的时候还是可以大大的减少网络流量的。本节主要本别介绍对单个文件、多个文件的压缩。解压这里就不讲了,解压的话没什么实际意义,因为文件压缩后为zip格式的文件,现在windows系统解压这个格式的文件真是特多了。我个人认为这个压缩文件的功能在以下场景使用就比较合理:比如某运行的系统,在每天或者每周的固定时间会导出一批报表,如果我们不对导出的报表进行压缩,那么磁盘空间会大幅度的增加,如果我们对导出的文件进行压缩,那么磁盘空间的开销就会大大节省。
2.文件压缩的中文问题
中文,一直是个头疼的问题,同样,在这里我们对文件压缩也会出现中文乱码问题。对压缩的文件,如果文件名称是中文,压缩完成后,可以看到压缩包中的文件名称是乱码(文件的内容有中文,压缩后不会出现中文乱码问题),对于这种情况我们只要用ANT中的ant.jar中的类就可以解决此问题。压缩过程中会用到ZipEntry和ZipOutputStream类,如果我采用第一种方式,这样就会出现中文乱码;如果我采用第二种方式,中文乱码问题就可以解决。文件运行的对比效果我会在后面把截图贴出来做一下对比。
第一种方式:
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
以上采用JDK API中自带的类时压缩的文件名会出现中文乱码
第二种方式:
import org.apache.tools.zip.ZipEntry; import org.apache.tools.zip.ZipOutputStream;
以上采用ANT中ant.jar包的类可以解决压缩的文件名的中文乱码问题
3.下载jar包
对于本节我只需要一个jar包,即ant.jar,提供jar包的下载路径如下:
http://files.cnblogs.com/java-pan/jar-ant.rar
4.method&class
ZipEntry:
ZipOutputStream:
5.代码文件
ZipFileUtil.java
[html] view plaincopyprint?
- packagezip;importjava.io.File;importjava.io.FileInputStream;importjava.io.FileOutputStream;importjava.io.IOException;/**采用JDKAPI中自带的类时压缩的文件会出现中文乱码*///importjava.util.zip.ZipEntry;//importjava.util.zip.ZipOutputStream;/**采用ANT中ant.jar包的类可以解决中文乱码问题*/importorg.apache.tools.zip.ZipEntry;importorg.apache.tools.zip.ZipOutputStream;/***Module:ZipFileUtil.java*Description:用zip对单个和多个文件进行压缩*Company:xxx*Version:1.0.0*Author:pantp*Date:May24,2012*/publicclassZipFileUtil{publicstaticvoidmain(String[]args)throwsException{/**测试单个文件的ZIP压缩*指定文件路径可以是绝对路径,也可以是相对路径*/Stringfile="src/zip/文件1.txt";StringzipFile1="src/zip/单个文件压缩.zip";booleanflag1=zipSingleFile(file,zipFile1);System.out.println("\n**************压缩【单】个文件<author:pantp>******************************\n");if(flag1){System.out.println("单个文件ZIP压缩成功,压缩后文件所在路径为:"+zipFile1);}else{System.out.println("单个文件ZIP压缩失败");}System.out.println("\n*******************************************************************************");/**测试多个文件的ZIP压缩*指定文件路径可以是绝对路径,也可以是相对路径*//*Stringfiles[]={"src/zip/文件1.txt","src/zip/file2.txt"};StringzipFile2="src/zip/多个文件压缩.zip";booleanflag2=zipFiles(files,zipFile2);System.out.println("\n**************压缩【多】个文件<author:pantp>******************************\n");if(flag2){System.out.println("多个文件ZIP压缩成功,压缩后文件所在路径为:"+zipFile2);}else{System.out.println("多个文件ZIP压缩失败");}System.out.println("\n*******************************************************************************");*/}/***<p>*@paramfile待压缩文件的名称例如,src/zip/文件1.txt*@paramzipFile压缩后文件的名称例如,src/zip/单个文件压缩.zip*@returnboolean*@throws:IOException*@Function:zipSingleFile*@Description:单个文件的压缩*@version:v1.0.0*@author:pantp*@Date:May24,2012*</p>*ModificationHistory:*DateAuthorVersionDescription*———————————————————————*May24,2012pantpv1.0.0Create*/publicstaticbooleanzipSingleFile(Stringfile,StringzipFile)throwsIOException{booleanbf=true;Filef=newFile(file);if(!f.exists()){System.out.println("文件不存在");bf=false;}else{Fileff=newFile(zipFile);if(!f.exists()){ff.createNewFile();}//创建文件输入流对象FileInputStreamin=newFileInputStream(file);//创建文件输出流对象FileOutputStreamout=newFileOutputStream(zipFile);//创建ZIP数据输出流对象ZipOutputStreamzipOut=newZipOutputStream(out);//得到文件名称StringfileName=file.substring(file.lastIndexOf(‘/’)+1,file.length());//创建指向压缩原始文件的入口ZipEntryentry=newZipEntry(fileName);zipOut.putNextEntry(entry);//向压缩文件中输出数据intnumber=0;byte[]buffer=newbyte[512];while((number=in.read(buffer))!=-1){zipOut.write(buffer,0,number);}zipOut.close();out.close();in.close();}returnbf;}/***<p>*@paramfiles待压缩的文件列表例如,src/zip/文件1.txt,src/zip/file2.txt*@paramzipfile压缩后的文件名称例如,src/zip/多个文件压缩.zip*@returnboolean*@throws:Exception*@Function:zipFiles*@Description:多个文件的ZIP压缩*@version:v1.0.0*@author:pantp*@Date:May24,2012*</p>*ModificationHistory:*DateAuthorVersionDescription*———————————————————————*May24,2012pantpv1.0.0Create*/publicstaticbooleanzipFiles(String[]files,Stringzipfile)throwsException{booleanbf=true;//根据文件路径构造一个文件实例Fileff=newFile(zipfile);//判断目前文件是否存在,如果不存在,则新建一个if(!ff.exists()){ff.createNewFile();}//根据文件路径构造一个文件输出流FileOutputStreamout=newFileOutputStream(zipfile);//传入文件输出流对象,创建ZIP数据输出流对象ZipOutputStreamzipOut=newZipOutputStream(out);//循环待压缩的文件列表for(inti=0;i<files.length;i++){Filef=newFile(files[i]);if(!f.exists()){bf=false;}try{//创建文件输入流对象FileInputStreamin=newFileInputStream(files[i]);//得到当前文件的文件名称StringfileName=files[i].substring(files[i].lastIndexOf(‘/’)+1,files[i].length());//创建指向压缩原始文件的入口ZipEntryentry=newZipEntry(fileName);zipOut.putNextEntry(entry);//向压缩文件中输出数据intnNumber=0;byte[]buffer=newbyte[512];while((nNumber=in.read(buffer))!=-1){zipOut.write(buffer,0,nNumber);}//关闭创建的流对象in.close();}catch(IOExceptione){e.printStackTrace();bf=false;}}zipOut.close();out.close();returnbf;}}
package zip; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; /* * 采用JDK API中自带的类时压缩的文件会出现中文乱码 */ //import java.util.zip.ZipEntry; //import java.util.zip.ZipOutputStream; /* * 采用ANT中ant.jar包的类可以解决中文乱码问题 */ import org.apache.tools.zip.ZipEntry; import org.apache.tools.zip.ZipOutputStream; /** *Module: ZipFileUtil.java *Description: 用zip对单个和多个文件进行压缩 *Company: xxx *Version: 1.0.0 *Author: pantp *Date: May 24, 2012 */ public class ZipFileUtil { public static void main(String[] args) throws Exception { /* * 测试单个文件的ZIP压缩 * 指定文件路径可以是绝对路径,也可以是相对路径 */ String file = "src/zip/文件1.txt"; String zipFile1 = "src/zip/单个文件压缩.zip"; boolean flag1 = zipSingleFile(file, zipFile1); System.out.println("\n**************压缩【单】个文件<author:pantp>******************************\n"); if (flag1) { System.out.println("单个文件ZIP压缩成功,压缩后文件所在路径为:"+zipFile1); } else { System.out.println("单个文件ZIP压缩失败"); } System.out.println("\n*******************************************************************************"); /* * 测试多个文件的ZIP压缩 * 指定文件路径可以是绝对路径,也可以是相对路径 */ /* String files[] = { "src/zip/文件1.txt", "src/zip/file2.txt" }; String zipFile2 = "src/zip/多个文件压缩.zip"; boolean flag2 = zipFiles(files, zipFile2); System.out.println("\n**************压缩【多】个文件<author:pantp>******************************\n"); if (flag2) { System.out.println("多个文件ZIP压缩成功,压缩后文件所在路径为:"+zipFile2); } else { System.out.println("多个文件ZIP压缩失败"); } System.out.println("\n*******************************************************************************"); */ } /** *<p> *@param file 待压缩文件的名称 例如,src/zip/文件1.txt *@param zipFile 压缩后文件的名称 例如,src/zip/单个文件压缩.zip *@return boolean *@throws :IOException *@Function: zipSingleFile *@Description:单个文件的压缩 *@version : v1.0.0 *@author: pantp *@Date:May 24, 2012 *</p> *Modification History: * Date Author Version Description * --------------------------------------------------------------------- * May 24, 2012 pantp v1.0.0 Create */ public static boolean zipSingleFile(String file, String zipFile) throws IOException { boolean bf = true; File f = new File(file); if (!f.exists()) { System.out.println("文件不存在"); bf = false; } else { File ff = new File(zipFile); if (!f.exists()) { ff.createNewFile(); } // 创建文件输入流对象 FileInputStream in = new FileInputStream(file); // 创建文件输出流对象 FileOutputStream out = new FileOutputStream(zipFile); // 创建ZIP数据输出流对象 ZipOutputStream zipOut = new ZipOutputStream(out); // 得到文件名称 String fileName = file.substring(file.lastIndexOf('/') + 1, file.length()); // 创建指向压缩原始文件的入口 ZipEntry entry = new ZipEntry(fileName); zipOut.putNextEntry(entry); // 向压缩文件中输出数据 int number = 0; byte[] buffer = new byte[512]; while ((number = in.read(buffer)) != -1) { zipOut.write(buffer, 0, number); } zipOut.close(); out.close(); in.close(); } return bf; } /** *<p> *@param files 待压缩的文件列表 例如,src/zip/文件1.txt, src/zip/file2.txt *@param zipfile 压缩后的文件名称 例如,src/zip/多个文件压缩.zip *@return boolean *@throws :Exception *@Function: zipFiles *@Description:多个文件的ZIP压缩 *@version : v1.0.0 *@author: pantp *@Date:May 24, 2012 *</p> *Modification History: * Date Author Version Description * --------------------------------------------------------------------- * May 24, 2012 pantp v1.0.0 Create */ public static boolean zipFiles(String[] files, String zipfile) throws Exception { boolean bf = true; // 根据文件路径构造一个文件实例 File ff = new File(zipfile); // 判断目前文件是否存在,如果不存在,则新建一个 if (!ff.exists()) { ff.createNewFile(); } // 根据文件路径构造一个文件输出流 FileOutputStream out = new FileOutputStream(zipfile); // 传入文件输出流对象,创建ZIP数据输出流对象 ZipOutputStream zipOut = new ZipOutputStream(out); // 循环待压缩的文件列表 for (int i = 0; i < files.length; i++) { File f = new File(files[i]); if (!f.exists()) { bf = false; } try { // 创建文件输入流对象 FileInputStream in = new FileInputStream(files[i]); // 得到当前文件的文件名称 String fileName = files[i].substring( files[i].lastIndexOf('/') + 1, files[i].length()); // 创建指向压缩原始文件的入口 ZipEntry entry = new ZipEntry(fileName); zipOut.putNextEntry(entry); // 向压缩文件中输出数据 int nNumber = 0; byte[] buffer = new byte[512]; while ((nNumber = in.read(buffer)) != -1) { zipOut.write(buffer, 0, nNumber); } // 关闭创建的流对象 in.close(); } catch (IOException e) { e.printStackTrace(); bf = false; } } zipOut.close(); out.close(); return bf; } }
6.运行测试
(1)在项目的src的zip目录下新建以下2个测试文件
文件1.txt
file2.txt
(2)运行main方法中单个文件压缩的方法,运行结果如图:
后台日志如下:
生成的zip文件如下:
(3)运行main方法中多个文件压缩的方法,运行结果如图:
后台日志如下:
生成的zip文件如下:
压缩后的文件中不会出现中文乱码问题,打开多个文件压缩.zip文件中的文件1.txt,内容如下:
采用JDK自带的类会出现中文乱码问题,效果如图:
而只有在充满了艰辛的人生旅途中,