Java将一个文件下多个文件压缩并下载,文件夹目录如下:
每个文件下都有文件,要求实现将文件夹"A20240105_检查"压缩成"A20240105_检查.zip",
文件夹A20240105_检查下有子文件,每个子文件均有内容
工具类ZipUtils:
package com.somnus.zip;
import org.apache.commons.io.IOUtils;
import org.apache.tools.zip.ZipEntry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.util.zip.ZipOutputStream;
/**
* @Description:压缩文件工具类
* @Author: Asan
* @Date: 2022-05-18 8:31
*/
public class ZipUtils {
private static final Logger LOGGER = LoggerFactory.getLogger(ZipUtils.class);
/**
* 压缩文件
* @param zipFilePath 需要被压缩的文件绝对路径
* @param zipFilePathName 压缩后的文件绝对路径(带后缀名)
*/
public static void zip(String zipFilePath,String zipFilePathName){
ZipOutputStream zos=null;
try {
//创建压缩后的文件路径
FileOutputStream fos = new FileOutputStream(zipFilePathName);
zos=new ZipOutputStream(fos);
File file=new File(zipFilePath);
compress(zos,file,"");
LOGGER.info("zip finish");
} catch (FileNotFoundException e) {
LOGGER.error("FileNotFoundException:{}",e);
} catch (IOException e) {
LOGGER.error("IOException:{}",e);
} finally {
IOUtils.closeQuietly(zos);
}
}
/**
* 压缩文件:压缩一个目录下所有文件及文件夹
* @param zos 压缩输出流
* @param file 被压缩文件绝对路径
* @param base 被压缩文件名
*/
private static void compress(ZipOutputStream zos,File file,String base) throws IOException {
LOGGER.info("zipping:{}",file.getName());
//判断当前文件是目录还是文件
if(file.isDirectory()){
File[] files=file.listFiles();
zos.putNextEntry(new ZipEntry(base+file.getName()+"/"));
for(int i=0;i<files.length;i++){
//递归压缩文件
compress(zos,files[i],base+file.getName()+"/");
}
}else{
zos.putNextEntry(new ZipEntry(base+file.getName()));
FileInputStream fis=new FileInputStream(file);
byte[] buffer=new byte[1024*2];
int len;
while((len=fis.read(buffer))!=-1){
zos.write(buffer,0,len);
}
fis.close();
}
}
public static void main(String[] args) {
//测试压缩文件
String zipFilePath="E:\\home\\was\\data\\uploadPath\\A20240105_检查";
String zipFilePathName="E:\\home\\was\\data\\uploadPath\\A20240105_检查.zip";
zip(zipFilePath,zipFilePathName);
}
}
上面这个工具类可以运行main方法,允许后生成压缩文件
实际工作中运用调用如下:
package com.somnus.custom;
import com.somnus.zip.ZipUtils;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.OutputStream;
/**
* @Author: Asan
* @Date: 2024/1/5 19:35
* @Description:
*/
@Controller
@RequestMapping("/demoTest")
public class DemoTestController {
//log日志
private static final Logger LOGGER = LoggerFactory.getLogger(DemoTestController.class);
/**
* 测试下载压缩包
* @param request
* @param response
*/
@RequestMapping(value = "/batchDownload.do")
public void batchDownLoad(HttpServletRequest request, HttpServletResponse response) {
FileInputStream fis = null;
OutputStream os = null;
try {
//设置页面静态文字中文编码
response.setCharacterEncoding("UTF-8");
//压缩目录:为了本地测试写了本地地址,实际工作中写服务器地址
String dateDir = "E:\\home\\was\\data\\uploadPath\\";
//压缩名:实际工作中写定义的压缩名如系统当前时间+6位随机数(zipDirName = DateUtils.getCurrYYYYMMDD() + "_" + RandomUtils.randomByNumber(6))
String zipDirName = "A20240105_检查";
//定义临时压缩文件名
String zipName = zipDirName + ".zip";
//下面建打zip包用的子目录:E:\\home\\was\data\\uploadPath\\A20240105_检查\\
String targetFilePath = dateDir + zipDirName + File.separator;
//判断是否存在该临时目录,没有就建立
File targetPath = new File(targetFilePath);
if (!targetPath.exists()) {
targetPath.mkdirs();
}
//压缩后的文件名路径:E:\\home\\was\data\\uploadPath\\A20240105_检查.zip
String downLoadFile = dateDir + zipDirName + ".zip";
//压缩文件(调用工具类)
ZipUtils.zip(downLoadFile, targetFilePath);
//创建zip文件
File file = new File(downLoadFile);
fis = new FileInputStream(file);
os = response.getOutputStream();
zipName = new String(zipName.getBytes("UTF-8"), "ISO8859-1");//文件名解决中文乱码:该方法从浏览器下载中文名正常展示
//重置,清除缓存
response.reset();
//附件下载且UTF-8编码
response.setContentType("application/x-download;charset=UTF-8");
//附件下载中文乱码问题:该方法从浏览器下载中文名正常展示
response.addHeader("Content-Disposition", "attachment;filename=" + zipName);
//附件下载文件长度
response.addHeader("Content-Length", "" + (int) file.length());
int len;
byte[] buffer = new byte[8192];
while ((len = fis.read(buffer)) > 0) {
os.write(buffer, 0, len);
os.flush();
}
} catch (Exception e) {
e.getMessage();
LOGGER.error("附件下载失败!", e);
} finally {
IOUtils.closeQuietly(os);
IOUtils.closeQuietly(fis);
}
}
}
在实际工作中,web项目批量下载附件,直接复制这个测试类即可。本人搭建springboot项目,在浏览器允许直接下载压缩文件。
桌面效果:
备注:以上代码,实际工作中能够正常运用,调用压缩工具类主要是压缩后的文件名绝对地址,需要被压缩的文件绝对路径,最后创建压缩文件,输出流读取输出