本节摘要:本节摘要介绍对文件的压缩。
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

1 package zip; 2 3 import java.io.File; 4 import java.io.FileInputStream; 5 import java.io.FileOutputStream; 6 import java.io.IOException; 7 8 /* 9 * 采用JDK API中自带的类时压缩的文件会出现中文乱码 10 */ 11 //import java.util.zip.ZipEntry; 12 //import java.util.zip.ZipOutputStream; 13 14 /* 15 * 采用ANT中ant.jar包的类可以解决中文乱码问题 16 */ 17 import org.apache.tools.zip.ZipEntry; 18 import org.apache.tools.zip.ZipOutputStream; 19 20 /** 21 *Module: ZipFileUtil.java 22 *Description: 用zip对单个和多个文件进行压缩 23 *Company: xxx 24 *Version: 1.0.0 25 *Author: pantp 26 *Date: May 24, 2012 27 */ 28 public class ZipFileUtil { 29 30 public static void main(String[] args) throws Exception { 31 32 /* 33 * 测试单个文件的ZIP压缩 34 * 指定文件路径可以是绝对路径,也可以是相对路径 35 */ 36 String file = "src/zip/文件1.txt"; 37 String zipFile1 = "src/zip/单个文件压缩.zip"; 38 boolean flag1 = zipSingleFile(file, zipFile1); 39 System.out.println("\n**************压缩【单】个文件<author:pantp>******************************\n"); 40 if (flag1) { 41 System.out.println("单个文件ZIP压缩成功,压缩后文件所在路径为:"+zipFile1); 42 } else { 43 System.out.println("单个文件ZIP压缩失败"); 44 } 45 System.out.println("\n*******************************************************************************"); 46 47 /* 48 * 测试多个文件的ZIP压缩 49 * 指定文件路径可以是绝对路径,也可以是相对路径 50 */ 51 /* String files[] = { "src/zip/文件1.txt", "src/zip/file2.txt" }; 52 String zipFile2 = "src/zip/多个文件压缩.zip"; 53 boolean flag2 = zipFiles(files, zipFile2); 54 System.out.println("\n**************压缩【多】个文件<author:pantp>******************************\n"); 55 if (flag2) { 56 System.out.println("多个文件ZIP压缩成功,压缩后文件所在路径为:"+zipFile2); 57 } else { 58 System.out.println("多个文件ZIP压缩失败"); 59 } 60 System.out.println("\n*******************************************************************************"); 61 */ 62 } 63 64 /** 65 *<p> 66 *@param file 待压缩文件的名称 例如,src/zip/文件1.txt 67 *@param zipFile 压缩后文件的名称 例如,src/zip/单个文件压缩.zip 68 *@return boolean 69 *@throws :IOException 70 *@Function: zipSingleFile 71 *@Description:单个文件的压缩 72 *@version : v1.0.0 73 *@author: pantp 74 *@Date:May 24, 2012 75 *</p> 76 *Modification History: 77 * Date Author Version Description 78 * --------------------------------------------------------------------- 79 * May 24, 2012 pantp v1.0.0 Create 80 */ 81 public static boolean zipSingleFile(String file, String zipFile) 82 throws IOException { 83 boolean bf = true; 84 File f = new File(file); 85 if (!f.exists()) { 86 System.out.println("文件不存在"); 87 bf = false; 88 } else { 89 File ff = new File(zipFile); 90 if (!f.exists()) { 91 ff.createNewFile(); 92 } 93 // 创建文件输入流对象 94 FileInputStream in = new FileInputStream(file); 95 // 创建文件输出流对象 96 FileOutputStream out = new FileOutputStream(zipFile); 97 // 创建ZIP数据输出流对象 98 ZipOutputStream zipOut = new ZipOutputStream(out); 99 // 得到文件名称 100 String fileName = file.substring(file.lastIndexOf('/') + 1, file.length()); 101 // 创建指向压缩原始文件的入口 102 ZipEntry entry = new ZipEntry(fileName); 103 zipOut.putNextEntry(entry); 104 // 向压缩文件中输出数据 105 int number = 0; 106 byte[] buffer = new byte[512]; 107 while ((number = in.read(buffer)) != -1) { 108 zipOut.write(buffer, 0, number); 109 } 110 zipOut.close(); 111 out.close(); 112 in.close(); 113 } 114 return bf; 115 } 116 117 /** 118 *<p> 119 *@param files 待压缩的文件列表 例如,src/zip/文件1.txt, src/zip/file2.txt 120 *@param zipfile 压缩后的文件名称 例如,src/zip/多个文件压缩.zip 121 *@return boolean 122 *@throws :Exception 123 *@Function: zipFiles 124 *@Description:多个文件的ZIP压缩 125 *@version : v1.0.0 126 *@author: pantp 127 *@Date:May 24, 2012 128 *</p> 129 *Modification History: 130 * Date Author Version Description 131 * --------------------------------------------------------------------- 132 * May 24, 2012 pantp v1.0.0 Create 133 */ 134 public static boolean zipFiles(String[] files, String zipfile) 135 throws Exception { 136 boolean bf = true; 137 138 // 根据文件路径构造一个文件实例 139 File ff = new File(zipfile); 140 // 判断目前文件是否存在,如果不存在,则新建一个 141 if (!ff.exists()) { 142 ff.createNewFile(); 143 } 144 // 根据文件路径构造一个文件输出流 145 FileOutputStream out = new FileOutputStream(zipfile); 146 // 传入文件输出流对象,创建ZIP数据输出流对象 147 ZipOutputStream zipOut = new ZipOutputStream(out); 148 149 // 循环待压缩的文件列表 150 for (int i = 0; i < files.length; i++) { 151 File f = new File(files[i]); 152 if (!f.exists()) { 153 bf = false; 154 } 155 try { 156 // 创建文件输入流对象 157 FileInputStream in = new FileInputStream(files[i]); 158 // 得到当前文件的文件名称 159 String fileName = files[i].substring( 160 files[i].lastIndexOf('/') + 1, files[i].length()); 161 // 创建指向压缩原始文件的入口 162 ZipEntry entry = new ZipEntry(fileName); 163 zipOut.putNextEntry(entry); 164 // 向压缩文件中输出数据 165 int nNumber = 0; 166 byte[] buffer = new byte[512]; 167 while ((nNumber = in.read(buffer)) != -1) { 168 zipOut.write(buffer, 0, nNumber); 169 } 170 // 关闭创建的流对象 171 in.close(); 172 } catch (IOException e) { 173 e.printStackTrace(); 174 bf = false; 175 } 176 } 177 zipOut.close(); 178 out.close(); 179 return bf; 180 } 181 182 }
6.运行测试
(1)在项目的src的zip目录下新建以下2个测试文件
文件1.txt
file2.txt
(2)运行main方法中单个文件压缩的方法,运行结果如图:
后台日志如下:
生成的zip文件如下:
*(
(3)运行main方法中多个文件压缩的方法,运行结果如图:
后台日志如下:
生成的zip文件如下:
压缩后的文件中不会出现中文乱码问题,打开多个文件压缩.zip文件中的文件1.txt,内容如下:
采用JDK自带的类会出现中文乱码问题,效果如图: