思路:根据需要打包的文件夹的路径找出该文件夹,递归遍历文件夹中的所有文件压缩到目标zip文件中,然后读取zip文件,用流的形式输出到客户端,然后将生成的zip文件进行物理删除。
1.controller层
//批量下载文件压缩包
@RequestMapping("/downloadSomeFiles")
public void downloadSomeFiles(HttpServletResponse resp){
//打包成zip
fileToZip(resp,sourceTargetPath,zipFilePath,fileName);
}
2.打包成zip的方法(fileToZip)
/**
*
* <B>方法描述:</B>(将某个文件夹打包成压缩文件进行下载) <br/>
*
* <B>作者: </B> zgx <br/>
* <B>创建日期:</B> 2020年4月21日 上午8:51:50
* @param 参数 sourceFilePath:源文件路径(如"D:/workplace/myproject/files/myfolder",myfolder为我们需要打包的文件夹)
* @param 参数 zipFilePath:目标路径(如"D/werkplace/myproject/files/myzip/",生成的zip文件将打包在此文件夹下)
* @param 参数 fileName:输出的zip文件名称
* @return
*/
public void fileToZip(HttpServletResponse resp,String sourceFilePath,String zipFilePath,String fileName){
try {
//创建zip输出流
ZipOutputStream out = new ZipOutputStream( new FileOutputStream(zipFilePath+fileName+".zip"));
//创建缓冲输出流
BufferedOutputStream bos = new BufferedOutputStream(out);
File sourceFile = new File(sourceFilePath);
//调用函数遍历文件夹内容
compress(out,bos,sourceFile,sourceFile.getName());
bos.close();
out.close();
System.out.println("压缩完成");
// 指定文件的保存类型。
resp.setContentType("application;charset=utf-8");
resp.setHeader("Content-disposition", "attachment; filename="+ new String( fileName.getBytes("gb2312"), "ISO8859-1" ) +".zip");
ServletOutputStream oupstream = resp.getOutputStream();
FileInputStream from = new FileInputStream(zipFilePath+fileName+".zip");
byte[] buffer = new byte[1024];
int bytes_read;
while ((bytes_read = from.read(buffer)) != -1) {
oupstream.write(buffer, 0, bytes_read);
}
//关掉输入输出流之后把压缩文件从系统中彻底删除
//提示:如果输入输出流没关闭,那么文件会被占用无法删除
oupstream.flush();
oupstream.close();
from.close();
deleteFile(zipFilePath+fileName+".zip");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
3.递归遍历文件夹中的文件压缩到zip文件中的方法(compress)
/**
*
* <B>方法描述:</B>(递归遍历文件压缩到zip文件中) <br/>
*
* <B>作者: </B> zgx <br/>
* <B>创建日期:</B> 2020年4月21日 上午8:50:58
* @param 参数
* @return
*/
public void compress(ZipOutputStream out,BufferedOutputStream bos,File sourceFile,String base) throws Exception
{
//如果路径为目录(文件夹)
if(sourceFile.isDirectory())
{
//取出文件夹中的文件(或子文件夹)
File[] flist = sourceFile.listFiles();
if(flist.length==0)//如果文件夹为空,则只需在目的地zip文件中写入一个目录进入点
{
System.out.println(base+"/");
out.putNextEntry( new ZipEntry(base+"/") );
}
else//如果文件夹不为空,则递归调用compress,文件夹中的每一个文件(或文件夹)进行压缩
{
for(int i=0;i<flist.length;i++)
{
compress(out,bos,flist[i],base+"/"+flist[i].getName());
}
}
}
else//如果不是目录(文件夹),即为文件,则先写入目录进入点,之后将文件写入zip文件中
{
out.putNextEntry( new ZipEntry(base) );
FileInputStream fos = new FileInputStream(sourceFile);
BufferedInputStream bis = new BufferedInputStream(fos);
int tag;
//将源文件写入到zip文件中
while((tag=bis.read())!=-1)
{
out.write(tag);
}
bis.close();
fos.close();
}
}
4.删除文件方法
public static Boolean deleteFile(String filePath){
try {
File dbFile = new File(filePath);
if (dbFile.exists()) {
dbFile.delete();
}
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}