由于需要,这几天研究了一下使用Java技术实现文件及文件夹打zip包及解zip包,使用的是java.util.zip包下的类;主要用到的是三个类,即:ZipEntry,我的理解是zip文件中压缩的一个个子文件;ZipInputStream是zip格式的输入流;ZipOutputStream是zip格式的输出流;
这方面网上也有一些例子,我也测试了相关的例子,但是在实现部分功能是有些不足,所以将代码改造后重写如下,现在实现的功能是对单个文件的打包及解包,对一个文件夹(文件夹内文件及文件夹不限)的打包及解包;
使用Java核心库的不足就是如果对中文文件夹或文件打包后,文件名或文件夹名会出现乱码,虽然在window下可以正常的解压,解压后也能正常显示中文,但是对于Unix等系统则不具有通用性;网上能找的解决方式是使用Ant包中的zip类库,Ant重写了ZipOutputStream类,所以对于打包后正常显示中文没有问题,但是还是不能动态制定压制zip文件的编码;
1import java.io.File;
2import java.io.FileInputStream;
3import java.io.FileNotFoundException;
4import java.io.FileOutputStream;
5import java.io.IOException;
6import java.util.zip.ZipEntry;
7import java.util.zip.ZipInputStream;
8import java.util.zip.ZipOutputStream;
9
10/** *//**
11 * 使用java核心类库打包、解包zip文件,不足之处在于压缩中文名的文件时,在压缩包内中文字符是乱码,
12 * 在windows下解压后编码正常显示中文,而其他系统下则不能正常还原;
13 */
14public class TestZip {
15
16 /** *//**
17 * 定义压缩文件及目录为zip文件的方法,重写下面的zip方法
18 *
19 * @param zipFileName
20 * @param inputFile
21 * @throws Exception
22 */
23 public void zip(String zipFileName, String inputFile) {
24 zip(zipFileName, new File(inputFile));
25 }
26
27 /** *//**
28 * 定义压缩文件及目录为zip文件的方法,重写下面的zip方法
29 *
30 * @param zipFileName
31 * @param inputFile
32 * @throws Exception
33 */
34 public void zip(String zipFileName, File inputFile) {
35 try {
36 ZipOutputStream out = new ZipOutputStream(new FileOutputStream(
37 zipFileName));
38 zip(out, inputFile, inputFile.getName());
39 System.out.println("zip done");
40 out.close();
41 }
42 catch (FileNotFoundException e) {
43 // TODO 自动生成 catch 块
44 e.printStackTrace();
45 }
46 catch (IOException e) {
47 // TODO 自动生成 catch 块
48 e.printStackTrace();
49 }
50 }
51
52 /** *//**
53 * 定义压缩文件及目录为zip文件的方法
54 *
55 * @param out
56 * @param f
57 * @param base
58 * @throws Exception
59 */
60 public void zip(ZipOutputStream out, File f, String base) {
61 try {
62 System.out.println("Zipping " + f.getName());
63 //判断File是否为目录
64 if (f.isDirectory()) {
65 System.out.println("Read Directory !");
66 //获取f目录下所有文件及目录,作为一个File数组返回
67 File[] fl = f.listFiles();
68 out.putNextEntry(new ZipEntry(base + "/"));
69 base = base.length() == 0 ? "" : base + "/";
70 for (int i = 0; i < fl.length; i++) {
71 zip(out, fl[i], base + fl[i].getName());
72 }
73 }
74 else {
75 System.out.println("Read File !");
76 out.putNextEntry(new ZipEntry(base));
77 FileInputStream in = new FileInputStream(f);
78 int b;
79 System.out.println("base " + base);
80 while ((b = in.read()) != -1) {
81 // System.out.println("File reading");
82 out.write(b);
83 }
84 in.close();
85 }
86 }
87 catch (FileNotFoundException e) {
88 // TODO 自动生成 catch 块
89 e.printStackTrace();
90 }
91 catch (IOException e) {
92 // TODO 自动生成 catch 块
93 e.printStackTrace();
94 }
95 }
96
97 /** *//**
98 * 定义解压缩zip文件的方法
99 *
100 * @param zipFileName
101 * @param outputDirectory
102 */
103 public void unzip(String zipFileName, String outputDirectory) {
104 try {
105 ZipInputStream in = new ZipInputStream(new FileInputStream(
106 zipFileName));
107 //获取ZipInputStream中的ZipEntry条目,一个zip文件中可能包含多个ZipEntry,
108 //当getNextEntry方法的返回值为null,则代表ZipInputStream中没有下一个ZipEntry,
109 //输入流读取完成;
110 ZipEntry z = in.getNextEntry();
111 while (z != null) {
112 System.out.println("unziping " + z.getName());
113 //创建以zip包文件名为目录名的根目录
114 File f = new File(outputDirectory);
115 f.mkdir();
116 if (z.isDirectory()) {
117 String name = z.getName();
118 name = name.substring(0, name.length() - 1);
119// System.out.println("name " + name);
120 f = new File(outputDirectory + File.separator + name);
121 f.mkdir();
122// System.out.println("mkdir " + outputDirectory
123// + File.separator + name);
124 }
125 else {
126 f = new File(outputDirectory + File.separator + z.getName());
127 f.createNewFile();
128 FileOutputStream out = new FileOutputStream(f);
129 int b;
130 while ((b = in.read()) != -1) {
131 out.write(b);
132 }
133 out.close();
134 }
135 //读取下一个ZipEntry
136 z = in.getNextEntry();
137 }
138 in.close();
139 }
140 catch (FileNotFoundException e) {
141 // TODO 自动生成 catch 块
142 e.printStackTrace();
143 }
144 catch (IOException e) {
145 // TODO 自动生成 catch 块
146 e.printStackTrace();
147 }
148 }
149
150 public static void main(String[] args) {
151 TestZip t = new TestZip();
152// t.zip("c:\\test11.zip", "c:\\test1");
153// t.zip("c:\\test2.zip", "c:\\php");
154 t.unzip("c:\\test11.zip", "c:\\test11");
155 //如果此处不指定解压的具体目录,如:test2,那么则直接解压到根目录下
156// t.unzip("c:\\test2.zip", "c:\\test2");
157 }
158}