|
@@ -1,13 +1,17 @@
|
|
|
package com.ruoyi.common.utils.file;
|
|
|
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
+
|
|
|
+import javax.servlet.ServletOutputStream;
|
|
|
+import javax.servlet.http.HttpServletRequest;
|
|
|
import javax.servlet.http.HttpServletResponse;
|
|
|
-import java.io.BufferedInputStream;
|
|
|
-import java.io.BufferedOutputStream;
|
|
|
-import java.io.File;
|
|
|
-import java.io.FileInputStream;
|
|
|
+import java.io.*;
|
|
|
+import java.net.URLEncoder;
|
|
|
import java.util.zip.ZipEntry;
|
|
|
import java.util.zip.ZipOutputStream;
|
|
|
|
|
|
+import static org.springframework.util.FileCopyUtils.BUFFER_SIZE;
|
|
|
+
|
|
|
/**
|
|
|
* @program: microfront-server
|
|
|
* @description: 文件夹压缩为zip文件
|
|
@@ -16,72 +20,177 @@ import java.util.zip.ZipOutputStream;
|
|
|
*/
|
|
|
public class FolderToZipUtil {
|
|
|
|
|
|
- public static void zip(String sourceFileName, String objName,HttpServletResponse response){
|
|
|
- ZipOutputStream out = null;
|
|
|
- BufferedOutputStream bos = null;
|
|
|
+ /**
|
|
|
+ * 压缩文件夹https://www.cnblogs.com/zeng1994/p/7862288.html
|
|
|
+ *
|
|
|
+ * @param srcDir 要压缩的文件夹路径
|
|
|
+ * @param out
|
|
|
+ * @param KeepDirStructure true
|
|
|
+ * @throws RuntimeException
|
|
|
+ */
|
|
|
+ public static void toZip(String srcDir, OutputStream out, boolean KeepDirStructure) throws RuntimeException {
|
|
|
+
|
|
|
+ long start = System.currentTimeMillis();
|
|
|
+
|
|
|
+ ZipOutputStream zos = null;
|
|
|
+ File sourceFile = null;
|
|
|
try {
|
|
|
- //将zip以流的形式输出到前台
|
|
|
- response.setHeader("content-type", "application/octet-stream");
|
|
|
- response.setCharacterEncoding("utf-8");
|
|
|
- // 设置浏览器响应头对应的Content-disposition
|
|
|
- //参数中 testZip 为压缩包文件名,尾部的.zip 为文件后缀
|
|
|
- response.setHeader("Content-disposition",
|
|
|
- "attachment;filename=" + new String(objName.getBytes("gbk"), "iso8859-1")+".zip");
|
|
|
- //创建zip输出流
|
|
|
- out = new ZipOutputStream(response.getOutputStream());
|
|
|
- //创建缓冲输出流
|
|
|
- bos = new BufferedOutputStream(out);
|
|
|
- File sourceFile = new File(sourceFileName);
|
|
|
- //调用压缩函数
|
|
|
- compress(out, bos, sourceFile, sourceFile.getName());
|
|
|
- out.flush();
|
|
|
|
|
|
+ zos = new ZipOutputStream(out);
|
|
|
+ sourceFile = new File(srcDir);
|
|
|
+ compress(sourceFile, zos, sourceFile.getName(), KeepDirStructure);
|
|
|
+ long end = System.currentTimeMillis();
|
|
|
+ System.out.println("压缩完成,耗时:{}ms" + (end - start));
|
|
|
} catch (Exception e) {
|
|
|
- e.printStackTrace();
|
|
|
- }finally {
|
|
|
- IOCloseUtil.close(bos, out);
|
|
|
+ throw new RuntimeException("zip error from ZipUtils", e);
|
|
|
+ } finally {
|
|
|
+ if (zos != null) {
|
|
|
+ try {
|
|
|
+ zos.close();
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 删除压缩之前的文件夹
|
|
|
+ if (sourceFile != null) {
|
|
|
+// log.info("正在删除原文件");
|
|
|
+// deleteFolder(sourceFile);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+
|
|
|
/**
|
|
|
- * 文件压缩
|
|
|
- * @param out
|
|
|
- * @param bos
|
|
|
- * @param sourceFile
|
|
|
- * @param base
|
|
|
+ * 设置导出zip的响应格式
|
|
|
+ *
|
|
|
+ * @param request
|
|
|
+ * @param response
|
|
|
+ * @param fileZip zip的名字
|
|
|
+ * @param filePath zip的路径
|
|
|
+ * @throws UnsupportedEncodingException
|
|
|
*/
|
|
|
- public static void compress(ZipOutputStream out, BufferedOutputStream bos, File sourceFile, String base){
|
|
|
- FileInputStream fos = null;
|
|
|
- BufferedInputStream bis = null;
|
|
|
+ public static void downLoadFile(HttpServletRequest request, HttpServletResponse response, String fileZip, String filePath) throws UnsupportedEncodingException {
|
|
|
+
|
|
|
+ //进行浏览器下载
|
|
|
+ final String userAgent = request.getHeader("USER-AGENT");
|
|
|
+ //判断浏览器代理并分别设置响应给浏览器的编码格式
|
|
|
+ String finalFileName = null;
|
|
|
+ if (StringUtils.contains(userAgent, "MSIE") || StringUtils.contains(userAgent, "Trident")) {
|
|
|
+ // IE浏览器
|
|
|
+ finalFileName = URLEncoder.encode(fileZip, "UTF8");
|
|
|
+ System.out.println("IE浏览器");
|
|
|
+ } else if (StringUtils.contains(userAgent, "Mozilla")) {
|
|
|
+ // google,火狐浏览器
|
|
|
+ finalFileName = new String(fileZip.getBytes(), "ISO8859-1");
|
|
|
+ } else {
|
|
|
+ // 其他浏览器
|
|
|
+ finalFileName = URLEncoder.encode(fileZip, "UTF8");
|
|
|
+ }
|
|
|
+ // 告知浏览器下载文件,而不是直接打开,浏览器默认为打开
|
|
|
+ response.setContentType("application/x-download");
|
|
|
+ // 下载文件的名称
|
|
|
+ response.setHeader("Content-Disposition", "attachment;filename=\"" + finalFileName + "\"");
|
|
|
+
|
|
|
+ ServletOutputStream servletOutputStream = null;
|
|
|
try {
|
|
|
- //如果路径为目录(文件夹)
|
|
|
- if (sourceFile.isDirectory()) {
|
|
|
- //取出文件夹中的文件(或子文件夹)
|
|
|
- File[] flist = sourceFile.listFiles();
|
|
|
- if (flist.length == 0) {//如果文件夹为空,则只需在目的地zip文件中写入一个目录进入点
|
|
|
- out.putNextEntry(new ZipEntry(base + "/"));
|
|
|
- } else {//如果文件夹不为空,则递归调用compress,文件夹中的每一个文件(或文件夹)进行压缩
|
|
|
- for (int i = 0; i < flist.length; i++) {
|
|
|
- compress(out, bos, flist[i], base + "/" + flist[i].getName());
|
|
|
- }
|
|
|
+ servletOutputStream = response.getOutputStream();
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ DataOutputStream temps = new DataOutputStream(
|
|
|
+ servletOutputStream);
|
|
|
+ // 浏览器下载文件的路径
|
|
|
+ DataInputStream in = null;
|
|
|
+ try {
|
|
|
+ in = new DataInputStream(
|
|
|
+ new FileInputStream(filePath));
|
|
|
+ } catch (FileNotFoundException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ byte[] b = new byte[2048];
|
|
|
+ // 之后用来删除临时压缩文件
|
|
|
+ File reportZip = new File(filePath);
|
|
|
+ try {
|
|
|
+ while ((in.read(b)) != -1) {
|
|
|
+ temps.write(b);
|
|
|
+ }
|
|
|
+ temps.flush();
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ } finally {
|
|
|
+ if (temps != null) {
|
|
|
+ try {
|
|
|
+ temps.close();
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (in != null) {
|
|
|
+ try {
|
|
|
+ in.close();
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
}
|
|
|
- } else {//如果不是目录(文件夹),即为文件,则先写入目录进入点,之后将文件写入zip文件中
|
|
|
- out.putNextEntry(new ZipEntry(base));
|
|
|
- fos = new FileInputStream(sourceFile);
|
|
|
- bis = new BufferedInputStream(fos);
|
|
|
+ }
|
|
|
+ if (reportZip != null) {
|
|
|
+ // 删除服务器本地产生的临时压缩文件!
|
|
|
+ reportZip.delete();
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ servletOutputStream.close();
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- int tag;
|
|
|
- //将源文件写入到zip文件中
|
|
|
- while ((tag = bis.read()) != -1) {
|
|
|
- out.write(tag);
|
|
|
+ /**
|
|
|
+ * 递归压缩方法
|
|
|
+ *
|
|
|
+ * @param sourceFile 源文件
|
|
|
+ * @param zos zip输出流
|
|
|
+ * @param name 压缩后的名称
|
|
|
+ * @param KeepDirStructure 是否保留原来的目录结构,true:保留目录结构;
|
|
|
+ * false:所有文件跑到压缩包根目录下(注意:不保留目录结构可能会出现同名文件,会压缩失败)
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ private 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);
|
|
|
+ }
|
|
|
}
|
|
|
- bis.close();
|
|
|
- fos.close();
|
|
|
}
|
|
|
- } catch (Exception e) {
|
|
|
- e.printStackTrace();
|
|
|
- }finally {
|
|
|
- IOCloseUtil.close(bis,fos);
|
|
|
}
|
|
|
}
|
|
|
}
|