控制器
@RequestMapper("download") public String zipFileByFileIds(List<UploadFileInfo> uploadFileInfos, Map<String, String> map) { // 创建临时文件夹 String projectId = map.get("projectId");//随便传入一个值即可 String projectName = map.get("projectName");//项目名称 String projectZipDirPath = uploadDir + File.separator + "projectFileZip" + File.separator + "user_" +随机id + File.separator + "project_" + projectId + File.separator; String projectZipDirPathTemp = projectZipDirPath + "temp" + File.separator; File zipDir = new File(projectZipDirPath); File zipDirTemp = new File(projectZipDirPathTemp); UploadFileUtil.deleteDir(zipDirTemp); UploadFileUtil.deleteDir(zipDir); zipDir.mkdirs(); zipDirTemp.mkdirs(); OutputStream outputStream = null; ZipOutputStream zipOutputStream = null; try { if (!CollectionUtils.isEmpty(uploadFileInfos)) { for (UploadFileInfo fileInfo : uploadFileInfos) { String filePath = fileInfo.getFilePath(); File file = new File(filePath); if (file.exists()) { File targetFile = new File(projectZipDirPathTemp + fileInfo.getFileName()); UploadFileUtil.copyFile(file, targetFile); } } // zip SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss"); File zipFile = new File(projectZipDirPath + File.separator + projectName + format.format(new Date()) + ".zip"); outputStream = new FileOutputStream(zipFile); zipOutputStream = new ZipOutputStream(outputStream); zipOutputStream.setEncoding(System.getProperty("sun.jnu.encoding")); UploadFileUtil.zipDir(projectZipDirPathTemp, zipOutputStream, ""); return zipFile.getPath(); } else { return null; } } catch (Exception e) { logger.error("压缩附件失败", e); } finally { if (zipOutputStream != null) { try { zipOutputStream.close(); } catch (IOException e) { logger.error("压缩附件失败", e); } } if (outputStream != null) { try { outputStream.close(); } catch (IOException e) { logger.error("压缩附件失败", e); } } } return null; }
工具类
package com.ds.xx.pm.util; import com.AjaxResult; import com.IdUtil; import com.PropertiesUtil; import com.UploadFileInfo; import org.apache.tools.zip.ZipEntry; import org.apache.tools.zip.ZipOutputStream; import org.springframework.web.multipart.MultipartFile; import java.io.*; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import static org.springframework.util.StreamUtils.BUFFER_SIZE; public class UploadFileUtil { //视频 private final static List<String> VIDEO_TYPE = Arrays.asList("avi", "mpg", "mpeg", "rm", "rmvb", "wmv", "mov", "mp4"); //图片 private final static List<String> PICTURE_TYPE = Arrays.asList("bpm", "jpg", "jpeg", "gif", "png", "psd", "tiff"); //文件 private final static List<String> FILE_TYPE = Arrays.asList("txt", "cvs", "pdf", "doc", "docx", "xlsx", "xls", "wps", "et", "ppt", "pptx", "dps"); //文件名称加时间 private static DateTimeFormatter sdf = DateTimeFormatter.ofPattern("yyyy-MM"); //时间 private static DateTimeFormatter sdfs = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); /** * 多文件上传工具类 * * @param files * @return */ public static List<UploadFileInfo> uploadFileList(MultipartFile[] files) { try { // 用来返回文件存入数据库后的信息 List<UploadFileInfo> dsCmsFileList = new ArrayList<UploadFileInfo>(); // 文件夹使用当前日期 LocalDateTime now = LocalDateTime.now(); String strDate = sdf.format(now); //通过工具类读取 配置路径 String uploadFilePath = PropertiesUtil.getProperties("ds.component.tool.uploadFilePath"); // 文件目录 String dirPath = uploadFilePath + File.separator + strDate; // 存入的文件夹 // 遍历文件,存入服务区并保存位置信息到数据库 for (int i = 0; i < files.length; i++) { String fileName = files[i].getOriginalFilename(); // 上传文件名称 String fileSuffix = fileName.substring(fileName.lastIndexOf(".") + 1); // 后缀 String wholeFileName = fileName.substring(0, fileName.lastIndexOf(".")) + "." + fileSuffix; //获取文件名 进行截取 //如果目录不存在 File fileDirPath = new File(dirPath); if (!fileDirPath.exists()) { //创建目录 fileDirPath.mkdirs(); } String name = IdUtil.shortUUID(); File file = new File(dirPath, name + "." + fileSuffix); //文件名去重 如果文件名存在则加1 /*String[] fileInfo = getFileInfo(wholeFileName); String toPrefix = fileInfo[0]; String toSuffix = fileInfo[1]; for (int j = 1; file.exists() && j < Integer.MAX_VALUE; j++) { file = new File(dirPath, toPrefix + '(' + j + ')' + toSuffix); }*/ if (fileDirPath.exists() && !file.isDirectory()) { file.createNewFile(); } files[i].transferTo(file); // 拷贝文件到指定位置 UploadFileInfo uploadFileInfo = new UploadFileInfo(); uploadFileInfo.setId(IdUtil.shortUUID()); uploadFileInfo.setFileName(wholeFileName); uploadFileInfo.setCreateTime(sdfs.format(LocalDateTime.now())); String fileUrl = dirPath; uploadFileInfo.setFilePath(fileUrl + File.separator + name + "." + fileSuffix); //添加要返回的数据 dsCmsFileList.add(uploadFileInfo); if (VIDEO_TYPE.contains(fileSuffix)) { // 视频文件 uploadFileInfo.setFileType("1"); } else if (PICTURE_TYPE.contains(fileSuffix)) { // 图片文件 uploadFileInfo.setFileType("0"); } else if (FILE_TYPE.contains(fileSuffix)) {//文件 uploadFileInfo.setFileType("2"); } } return dsCmsFileList; } catch (IOException e) { e.printStackTrace(); return null; } } /** * 单文件上传工具类 * * @param files files * @param columnAlias 栏目别名,用来防止shiro拦截栏目中文件 * @return 上传结果 */ public static AjaxResult uploadFile(MultipartFile files, String columnAlias) { try { // 用来返回文件存入数据库后的信息 List<UploadFileInfo> dsCmsFileList = new ArrayList<UploadFileInfo>(); // 文件夹使用当前日期 LocalDateTime now = LocalDateTime.now(); String strDate = sdf.format(now); //通过工具类读取 配置路径 String uploadFilePath = PropertiesUtil.getProperties("ds.component.uploadFilePath"); // 文件目录 String dirPath = uploadFilePath + File.separator + strDate; // 存入的文件夹 if (StringUtils.isNotNull(columnAlias)) { dirPath = uploadFilePath + File.separator + columnAlias + File.separator + strDate; // 存入的文件夹 } // 遍历文件,存入服务区并保存位置信息到数据库 String fileName = files.getOriginalFilename(); // 上传文件名称 String fileSuffix = fileName.substring(fileName.lastIndexOf(".") + 1); // 后缀 String wholeFileName = fileName.substring(0, fileName.lastIndexOf(".")) + "." + fileSuffix; //获取文件名 进行截取 //如果目录不存在 File fileDirPath = new File(dirPath); if (!fileDirPath.exists()) { //创建目录 fileDirPath.mkdirs(); } String name = IdUtil.shortUUID(); File file = new File(dirPath, name + "." + fileSuffix); if (fileDirPath.exists() && !file.isDirectory()) { file.createNewFile(); } files.transferTo(file); // 拷贝文件到指定位置 UploadFileInfo uploadFileInfo = new UploadFileInfo(); String id = IdUtil.shortUUID(); uploadFileInfo.setId(id); uploadFileInfo.setFileName(wholeFileName); uploadFileInfo.setCreateTime(sdf.format(LocalDateTime.now())); String fileUrl = dirPath; uploadFileInfo.setFilePath(fileUrl + File.separator + name + "." + fileSuffix); //添加要返回的数据 dsCmsFileList.add(uploadFileInfo); uploadFileInfo.setFileType("." + fileSuffix); return new AjaxResult("上传成功!", uploadFileInfo); } catch (IOException e) { e.printStackTrace(); return new AjaxResult("上传失败:" + e.getMessage(), null); } } /** * 根据path删除文件 * * @param path * @return */ public static String delFile(String path) { String resultInfo = null; File file = new File(path); if (file.exists()) { if (file.delete()) { resultInfo = "1-删除成功"; } else { resultInfo = "0-删除失败"; } } else { resultInfo = "文件不存在!"; } return resultInfo; } public static void deleteDir(File file) { if (file == null || !file.exists()) { return; } File[] files = file.listFiles(); if (files != null) { for (File f : files) { if (f.isDirectory()) { deleteDir(f); } else { f.delete(); } } file.delete(); } } /** * 递归压缩方法 * * @param sourceFile 源文件 * @param zos zip输出流 * @param name 压缩后的名称 * @param keepDirStructure 是否保留原来的目录结构,true:保留目录结构; * false:所有文件跑到压缩包根目录下(注意:不保留目录结构可能会出现同名文件,会压缩失败) * @throws Exception */ public static void compress(File sourceFile, ZipOutputStream zos, String name, boolean keepDirStructure) throws Exception { 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); } } } } } /** * 复制文件 * * @param resource * @param target */ public static void copyFile(File resource, File target) throws Exception { // 输入流 --> 从一个目标读取数据 // 输出流 --> 向一个目标写入数据 // 文件输入流并进行缓冲 FileInputStream inputStream = new FileInputStream(resource); BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream); // 文件输出流并进行缓冲 FileOutputStream outputStream = new FileOutputStream(target); BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream); // 缓冲数组 // 大文件 可将 1024 * 2 改大一些,但是 并不是越大就越快 byte[] bytes = new byte[1024 * 2]; int len = 0; while ((len = inputStream.read(bytes)) != -1) { bufferedOutputStream.write(bytes, 0, len); } // 刷新输出缓冲流 bufferedOutputStream.flush(); //关闭流 bufferedInputStream.close(); bufferedOutputStream.close(); inputStream.close(); outputStream.close(); } /** * 该方法递归实现将多个文件夹压缩在同一个zip包中 然后删除文件夹directoryName 下需要被压缩的文件。 * @param directoryName 文件夹路径 * @param zos 压缩流 ZipOutputStream 确定压缩包生成的位置 * @param basePath 用于传给 ZipEntry 用于压缩包分文件夹第一级传入可以为"" * @throws IOException */ public static void zipDir(String directoryName, ZipOutputStream zos, String basePath) { File file = new File(directoryName); // 每一级别的递归 basePath 不应该被改变所以添加一个 参数 copyBasePath String copyBasePath; if (file.exists()) { File[] fileList = file.listFiles(); for (File f : fileList) { if (f.isDirectory()) { // 拼接文件夹目录 if (!"".equals(basePath)) { copyBasePath = basePath+File.separator+f.getName(); } else { copyBasePath = f.getName(); } // 继续递归文件夹 zipDir(directoryName + File.separator + f.getName(), zos, copyBasePath); } else { // 压缩单个文件到 zos String zipName; if (!"".equals(basePath)) { zipName = basePath + File.separator + f.getName(); } else { zipName = f.getName(); } try { // zos.putNextEntry 开始添加压缩文件 ZipEntry传入的参数 zipName如果包含了层级关系就会生成文件夹 zos.putNextEntry(new ZipEntry(zipName)); int len; FileInputStream is = new FileInputStream(f); byte[] bytes = new byte[1024]; while ((len = is.read(bytes)) != -1) { zos.write(bytes, 0, len); } zos.flush(); zos.closeEntry(); is.close(); } catch (IOException e) { e.printStackTrace(); } } Boolean isDelete = f.delete(); System.out.println(f.getName()+"删除是否成功: "+isDelete); } } } }