|
有时候在系统中需要一次性下载多个文件,但逐个下载文件比较麻烦。这时候,最好的解决办法是将所有文件打包成一个压缩文件,然后下载这个压缩文件,这样就可以一次性获取所有所需的文件了。
下面是一个名为CompressUtil的工具类的代码,它提供了一些方法来处理文件压缩和下载操作:- import org.apache.commons.lang3.ArrayUtils;
- import org.apache.commons.lang3.StringUtils;
- import org.apache.lucene.util.RamUsageEstimator;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import javax.servlet.ServletOutputStream;
- import javax.servlet.http.HttpServletResponse;
- import java.io.*;
- import java.util.*;
- import java.util.zip.*;
- /**
- * @author fhey
- * @date 2023-05-11 20:48:28
- * @description: 压缩工具类
- */
- public class CompressUtil {
- private static final Logger logger = LoggerFactory.getLogger(CompressUtil.class);
- /**
- * 将文件打包到zip并创建文件
- *
- * @param sourceFilePath
- * @param zipFilePath
- * @throws IOException
- */
- public static void createLocalCompressFile(String sourceFilePath, String zipFilePath) throws IOException {
- createLocalCompressFile(sourceFilePath, zipFilePath, null);
- }
- /**
- * 将文件打包到zip并创建文件
- *
- * @param sourceFilePath
- * @param zipFilePath
- * @param zipName
- * @throws IOException
- */
- public static void createLocalCompressFile(String sourceFilePath, String zipFilePath, String zipName) throws IOException {
- File sourceFile = new File(sourceFilePath);
- if (!sourceFile.exists()) {
- throw new RuntimeException(sourceFilePath + "不存在!");
- }
- if(StringUtils.isBlank(zipName)){
- zipName = sourceFile.getName();
- }
- File zipFile = createNewFile(zipFilePath + File.separator + zipName + ".zip");
- try (FileOutputStream fileOutputStream = new FileOutputStream(zipFile)) {
- compressFile(sourceFile, fileOutputStream);
- }
- }
- /**
- * 获取压缩文件流
- *
- * @param sourceFilePath
- * @return ByteArrayOutputStream
- * @throws IOException
- */
- public static OutputStream compressFile(String sourceFilePath, OutputStream outputStream) throws IOException {
- File sourceFile = new File(sourceFilePath);
- if (!sourceFile.exists()) {
- throw new RuntimeException(sourceFilePath + "不存在!");
- }
- return compressFile(sourceFile, outputStream);
- }
- /**
- * 获取压缩文件流
- *
- * @param sourceFile
- * @return ByteArrayOutputStream
- * @throws IOException
- */
- private static OutputStream compressFile(File sourceFile, OutputStream outputStream) throws IOException {
- try (CheckedOutputStream checkedOutputStream = new CheckedOutputStream(outputStream, new CRC32());
- ZipOutputStream zipOutputStream = new ZipOutputStream(checkedOutputStream)) {
- doCompressFile(sourceFile, zipOutputStream, StringUtils.EMPTY);
- return outputStream;
- }
- }
- /**
- * 处理目录下的文件
- *
- * @param sourceFile
- * @param zipOutputStream
- * @param zipFilePath
- * @throws IOException
- */
- private static void doCompressFile(File sourceFile, ZipOutputStream zipOutputStream, String zipFilePath) throws IOException {
- // 如果文件是隐藏的,不进行压缩
- if (sourceFile.isHidden()) {
- return;
- }
- if (sourceFile.isDirectory()) {//如果是文件夹
- handDirectory(sourceFile, zipOutputStream, zipFilePath);
- } else {//如果是文件就添加到压缩包中
- try (FileInputStream fileInputStream = new FileInputStream(sourceFile)) {
- //String fileName = zipFilePath + File.separator + sourceFile.getName();
- String fileName = zipFilePath + sourceFile.getName();
- addCompressFile(fileInputStream, fileName, zipOutputStream);
- //String fileName = zipFilePath.replace("\", "/") + "/" + sourceFile.getName();
- //addCompressFile(fileInputStream, fileName, zipOutputStream);
- }
- }
- }
- /**
- * 处理文件夹
- *
- * @param dir 文件夹
- * @param zipOut 压缩包输出流
- * @param zipFilePath 压缩包中的文件夹路径
- * @throws IOException
- */
- private static void handDirectory(File dir, ZipOutputStream zipOut, String zipFilePath) throws IOException {
- File[] files = dir.listFiles();
- if (ArrayUtils.isEmpty(files)) {
- ZipEntry zipEntry = new ZipEntry(zipFilePath + dir.getName() + File.separator);
- zipOut.putNextEntry(zipEntry);
- zipOut.closeEntry();
- return;
- }
- for (File file : files) {
- doCompressFile(file, zipOut, zipFilePath + dir.getName() + File.separator);
- }
- }
- /**
- * 获取压缩文件流
- *
- * @param documentList 需要压缩的文件集合
- * @return ByteArrayOutputStream
- */
- public static OutputStream compressFile(List<FileInfo> documentList, OutputStream outputStream) {
- Map<String, List<FileInfo>> documentMap = new HashMap<>();
- documentMap.put("", documentList);
- return compressFile(documentMap, outputStream);
- }
- /**
- * 将文件打包到zip
- *
- * @param documentMap 需要下载的附件集合 map的key对应zip里的文件夹名
- * @return ByteArrayOutputStream
- */
- public static OutputStream compressFile(Map<String, List<FileInfo>> documentMap, OutputStream outputStream) {
- CheckedOutputStream checkedOutputStream = new CheckedOutputStream(outputStream, new CRC32());
- ZipOutputStream zipOutputStream = new ZipOutputStream(checkedOutputStream);
- try {
- for (Map.Entry<String, List<FileInfo>> documentListEntry : documentMap.entrySet()) {
- String dirName = documentMap.size() > 1 ? documentListEntry.getKey() : "";
- Map<String, Integer> fileNameToLen = new HashMap<>();//记录单个合同号文件夹下每个文件名称出现的次数(对重复文件名重命名)
- for (FileInfo document : documentListEntry.getValue()) {
- try {
- //防止单个文件夹下文件名重复 对重复的文件进行重命名
- String documentName = document.getFileName();
- if (fileNameToLen.get(documentName) == null) {
- fileNameToLen.put(documentName, 1);
- } else {
- int fileLen = fileNameToLen.get(documentName) + 1;
- fileNameToLen.put(documentName, fileLen);
- documentName = documentName + "(" + fileLen + ")";
- }
- String fileName = documentName + "." + document.getSuffix();
- if (StringUtils.isNotBlank(dirName)) {
- fileName = dirName + File.separator + fileName;
- }
- addCompressFile(document.getFileInputStream(), fileName, zipOutputStream);
- } catch (Exception e) {
- logger.info("filesToZip exception :", e);
- }
- }
- }
- } catch (Exception e) {
- logger.error("filesToZip exception:" + e.getMessage(), e);
- }
- return outputStream;
- }
- /**
- * 将单个文件写入文件压缩包
- *
- * @param inputStream 文件输入流
- * @param fileName 文件在压缩包中的相对全路径
- * @param zipOutputStream 压缩包输出流
- */
- private static void addCompressFile(InputStream inputStream, String fileName, ZipOutputStream zipOutputStream) {
- try (BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream)) {
- ZipEntry zipEntry = new ZipEntry(fileName);
- zipOutputStream.putNextEntry(zipEntry);
- byte[] bytes = new byte[1024];
- int length;
- while ((length = bufferedInputStream.read(bytes)) >= 0) {
- zipOutputStream.write(bytes, 0, length);
- zipOutputStream.flush();
- }
- zipOutputStream.closeEntry();
- //System.out.println("map size, value is " + RamUsageEstimator.sizeOf(zipOutputStream));
- } catch (Exception e) {
- logger.info("addFileToZip exception:", e);
- throw new RuntimeException(e);
- }
- }
- /**
- * 通过网络请求下载zip
- *
- * @param sourceFilePath 需要压缩的文件路径
- * @param response HttpServletResponse
- * @param zipName 压缩包名称
- * @throws IOException
- */
- public static void httpDownloadCompressFile(String sourceFilePath, HttpServletResponse response, String zipName) throws IOException {
- File sourceFile = new File(sourceFilePath);
- if (!sourceFile.exists()) {
- throw new RuntimeException(sourceFilePath + "不存在!");
- }
- if(StringUtils.isBlank(zipName)){
- zipName = sourceFile.getName();
- }
- try (ServletOutputStream servletOutputStream = response.getOutputStream()){
- CompressUtil.compressFile(sourceFile, servletOutputStream);
- response.setContentType("application/zip");
- response.setHeader("Content-Disposition", "attachment; filename="" + zipName + ".zip"");
- servletOutputStream.flush();
- }
- }
- public static void httpDownloadCompressFileOld(String sourceFilePath, HttpServletResponse response, String zipName) throws IOException {
- try (ServletOutputStream servletOutputStream = response.getOutputStream()){
- ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
- byte[] zipBytes = byteArrayOutputStream.toByteArray();
- response.setContentType("application/zip");
- response.setHeader("Content-Disposition", "attachment; filename="" + zipName + ".zip"");
- response.setContentLength(zipBytes.length);
- servletOutputStream.write(zipBytes);
- servletOutputStream.flush();
- }
- }
- /**
- * 通过网络请求下载zip
- *
- * @param sourceFilePath 需要压缩的文件路径
- * @param response HttpServletResponse
- * @throws IOException
- */
- public static void httpDownloadCompressFile(String sourceFilePath, HttpServletResponse response) throws IOException {
- httpDownloadCompressFile(sourceFilePath, response, null);
- }
- /**
- * 检查文件名是否已经存在,如果存在,就在文件名后面加上“(1)”,如果文件名“(1)”也存在,则改为“(2)”,以此类推。如果文件名不存在,就直接创建一个新文件。
- *
- * @param filename 文件名
- * @return File
- */
- public static File createNewFile(String filename) {
- File file = new File(filename);
- if (!file.exists()) {
- try {
- file.createNewFile();
- } catch (IOException e) {
- e.printStackTrace();
- }
- } else {
- String base = filename.substring(0, filename.lastIndexOf("."));
- String ext = filename.substring(filename.lastIndexOf("."));
- int i = 1;
- while (true) {
- String newFilename = base + "(" + i + ")" + ext;
- file = new File(newFilename);
- if (!file.exists()) {
- try {
- file.createNewFile();
- } catch (IOException e) {
- e.printStackTrace();
- }
- break;
- }
- i++;
- }
- }
- return file;
- }
- }
复制代码 FileInfo类代码:- /**
- * @author fhey
- * @date 2023-05-11 21:01:26
- * @description: TODO
- */
- @Data
- public class FileInfo {
- private InputStream fileInputStream;
- private String suffix;
- private String fileName;
-
- private boolean isDirectory;
- }
复制代码 测试压缩并在本地生成文件:- public static void main(String[] args) throws Exception {
- //在本地创建压缩文件
- CompressUtil.createLocalCompressFile("D:\\书籍\\电子书\\医书", "D:\\test");
- }
复制代码 压缩并在本地生成文件验证结果:
压缩文件并通过http请求下载:- /**
- * @author fhey
- */
- @RestController
- public class TestController {
- @GetMapping(value = "/testFileToZip")
- public void testFileToZip(HttpServletResponse response) throws IOException {
- String zipFileName = "myFiles";
- String sourceFilePath = "D:\\picture";
- CompressUtil.httpDownloadCompressFile(sourceFilePath,response, zipFileName);
- }
- }
复制代码 压缩文件并通过http请求下载验证结果:
来源:https://www.cnblogs.com/fhey/p/17433021.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作! |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|