ZIP压缩文件是一种非常常见的文件压缩形式,压缩后的文件可以节省存储空间,在java的内置类中提供了相关类,实现的方式也比较为简单。使用java.util.zip包中的ZipOutputStream与ZipInputStream类来实现文件的压缩/解压缩。如果要从ZIP压缩管理文件内读取某个文件,要首先找到对应文件的目录进入点,才能读取这个文件的内容。
ZipOutputStream对象,可以文件压缩为.zip文件。ZipOutputStream类构造方法如下
ZipOutputStream(OutputStream out)
ZipOutputStream类常用方法
putNextEntry(ZipEntry z):开始写一个新的ZipEntry,将流的位置移到此entry所指的开头
write(byte[]by,int off,int length) 将字节数组写入当前ZIP条目数据
setComment(String comment) 设置此ZIP文件的注释文字
示例:将指定文件下的文件压缩
html代码(form表单,获取压缩文件路径,使用POST方式提交到Servlet层)
<form action="${path }/FileServlet?methodName=compressFile" method="post" id="form1">
<input type="hidden" name="zipFile" id="zipFile">
<center>
<table border="0" width="500" >
<tr height="30">tr>
<tr><td width="40"> td>
<td align="right"> 文件路径:td>
<td ><input type="text" name="filePath" id="filePath" />
td>
tr><tr >
<td align="right">td>
<td colspan="2" align="center" >
<button type="submit" style="margin-top: 10px;margin-bottom: 10px" name="submit" class="layui-btn layui-btn-sm layui-btn-normal" >压缩button>
td>tr>
table>
center>
form>
Servlet代码 下面代码主要是获取到文件夹路径,然后调用zipFile方法来实现压缩文件夹中的所有子文件夹。
public void compressFile(HttpServletRequest request, HttpServletResponse res) {
try {
//省略了设置编码格式的代码
String filePath = request.getParameter("filePath"); //获取源文件夹路径
FileUtil fileUtil = new FileUtil();
if (filePath != null && !filePath.equals("")) {
File folder = new File(filePath);
File zipFile = new File(folder.getParent(), folder.getName() + ".zip");
zipFile.createNewFile();
zipFile(filePath, zipFile, folder.getParent());
res.getWriter().print("压缩成功");
}
else {
res.getWriter().print("NoFilePathFound");
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
zipFile方法代码如下 zipFile方法参数sourceFile表示要压缩的文件夹路径,targetZipFile为压缩后的文件路径,base为压缩文件夹的基本路径。先调用getFileList()
方法获取指定目录下的所有文件路径,然后根据targetZipFile创建文件输出流对象,创建Zip输出流对象,参数为文件输出流对象,创建字节数组,在遍历要所有要压缩的文件路径时使用压缩文件的相对路径来创建ZipEntry对象后,再将数据写入输出流中。(用完流记得关闭)
public void zipFile(String sourceFile, File targetZipFile, String base) throws IOException {
getFileList(sourceFile);
//创建文件输出流对象并传入压缩后的位置
FileOutputStream fileOutStream = new FileOutputStream(targetZipFile);
//用输出流对象创建Zip输出流对象
ZipOutputStream zipOutStream = new ZipOutputStream(fileOutStream);
byte[] by = new byte[1024];
for (String filePath : filePaths) {
File curFile = new File(filePath);
//使用相对路径来创建ZipEntry对象
ZipEntry entry = new ZipEntry(filePath.substring(base.length()+1, filePath.length()));
FileInputStream fileInStream = new FileInputStream(curFile);
zipOutStream.putNextEntry(entry);
int count = 0;
while ((count = fileInStream.read(by)) != -1) {
//将数据写入到Zip输出流中
zipOutStream.write(by, 0, count);
}
zipOutStream.closeEntry();//关闭ZipEntry对象
fileInStream.close();
}
zipOutStream.close();//释放
fileOutStream.close();
}
getFileList()方法:根据传过来的文件路径创建File对象,获取文件下的文件数组,循坏遍历判断文件数组是否当前文件是否是一个目录,如果是就继续调用该方法,不是将该文件路径添加到集合中
public void getFiles(String path) {
File dir = new File(path);
File files[] = dir.listFiles();
for (File file:files ) {
if (file.isDirectory()) //判断是否是目录
getFiles(file.getAbsolutePath());
else {
filePaths.add(file.getAbsolutePath());
}
}
}
效果