本文实例讲述了java实现的zip工具类。分享给大家供大家参考,具体如下:
实现把zip解压到指定路径,把文件夹压缩到zip,把文件列表压缩为zip的三个方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
|
import java.io.file;
import java.io.fileinputstream;
import java.io.fileoutputstream;
import java.io.ioexception;
import java.io.inputstream;
import java.io.outputstream;
import java.nio.charset.charset;
import java.util.arraylist;
import java.util.enumeration;
import java.util.list;
import java.util.zip.zipentry;
import java.util.zip.zipfile;
import java.util.zip.zipoutputstream;
public class ziputils
{
/**
* 解压zip到指定路径
* @param zipfile 待解压文件
* @param descdir 指定解压路径
* @return filenames 解压的全部文件名
* @throws ioexception
*/
public static list<string> unzipfiles(file zipfile, string descdir) throws ioexception
{
list<string> filenames = new arraylist<string>();
zipfile zip = new zipfile(zipfile,charset.forname( "gbk" )); //解决中文文件夹乱码
string name = zip.getname().substring(zip.getname().lastindexof( '\\' )+ 1 , zip.getname().lastindexof( '.' ));
file pathfile = new file(descdir+name);
if (!pathfile.exists())
{
pathfile.mkdirs();
}
string outpath = "" ;
for (enumeration<? extends zipentry> entries = zip.entries(); entries.hasmoreelements();)
{
zipentry entry = (zipentry) entries.nextelement();
string zipentryname = entry.getname();
filenames.add(zipentryname);
inputstream in = zip.getinputstream(entry);
outpath = (descdir + name + "/" + zipentryname).replaceall( "\\*" , "/" );
// 判断路径是否存在,不存在则创建文件路径
file file = new file(outpath.substring( 0 , outpath.lastindexof( '/' )));
if (!file.exists())
{
file.mkdirs();
}
// 判断文件全路径是否为文件夹,如果是上面已经上传,不需要解压
if ( new file(outpath).isdirectory())
{
continue ;
}
// 输出文件路径信息
fileoutputstream out = new fileoutputstream(outpath);
byte [] buf1 = new byte [ 1024 ];
int len;
while ((len = in.read(buf1)) > 0 ) {
out.write(buf1, 0 , len);
}
in.close();
out.close();
}
pathfile.delete();
return filenames;
}
/**
* 压缩文件夹成zip
* @param srcdir 待打包的文件夹路径
* @param out 打包文件名及存储路径
* @param keepdirstructure 是否保留文件夹结构 不保留则把文件夹下全部文件都打压在一起
* @throws runtimeexception
*/
public static void doctozip(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( "压缩完成,耗时:" + (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 压缩失败会抛出运行时异常
*/
public static void filestozip(list<file> srcfiles , outputstream out) throws runtimeexception
{
long start = system.currenttimemillis();
zipoutputstream zos = null ;
int buffer_size = 2 * 1024 ;
try
{
zos = new zipoutputstream(out);
for (file srcfile : srcfiles)
{
byte [] buf = new byte [buffer_size];
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( "压缩完成,耗时:" + (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 是否保留原来的目录结构,true:保留目录结构;
* false:所有文件跑到压缩包根目录下(注意:不保留目录结构可能会出现同名文件,会压缩失败)
* @throws exception
*/
private static void compress(file sourcefile, zipoutputstream zos, string name,
boolean keepdirstructure) throws exception
{
int buffer_size = 2 * 1024 ;
byte [] buf = new byte [buffer_size];
if (sourcefile.isfile())
{
// 向zip输出流中添加一个zip实体,构造器中name为zip实体的文件的名字
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 entry
zos.closeentry();
in.close();
} else
{
file[] listfiles = sourcefile.listfiles();
if (listfiles == null || listfiles.length == 0 )
{
// 需要保留原来的文件结构时,需要对空文件夹进行处理
if (keepdirstructure)
{
// 空文件夹的处理
zos.putnextentry( new zipentry(name + "/" ));
// 没有文件,不需要文件的copy
zos.closeentry();
}
} else
{
for (file file : listfiles)
{
// 判断是否需要保留原来的文件结构
if (keepdirstructure)
{
// 注意:file.getname()前面需要带上父文件夹的名字加一斜杠,
// 不然最后压缩包中就不能保留原来的文件结构,即:所有文件都跑到压缩包根目录下了
compress(file, zos, name + "/" + file.getname(),keepdirstructure);
} else
{
compress(file, zos, file.getname(),keepdirstructure);
}
}
}
}
}
}
|
希望本文所述对大家java程序设计有所帮助。
原文链接:https://blog.csdn.net/changquanzhu2969/article/details/80682309