话不多说,直接上代码
import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; import javax.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j;
@Slf4j public class ZipUtils { /** * 下载包压缩文件 * @param filename 最终压缩文件名称 * @param sourceFiles 源文件列表 * @param response */ public static void downloadZip(String filename,List<String> sourceFiles,HttpServletResponse response) { try { // 生成临时文件 File zipFile = new File(System.getProperty("java.io.tmpdir") + "/" + filename + ".zip"); if (!zipFile.exists()){ zipFile.createNewFile(); } //创建文件输出流 FileOutputStream fousa = new FileOutputStream(zipFile); ZipOutputStream zipOutA = new ZipOutputStream(fousa); zipFile(getFilesByPath(sourceFiles), zipOutA); zipOutA.close(); fousa.close(); // 以流的形式下载文件。 InputStream fis = new BufferedInputStream(new FileInputStream(zipFile.getPath())); byte[] buffer = new byte[fis.available()]; fis.read(buffer); fis.close(); // 清空response response.reset(); OutputStream toClient = new BufferedOutputStream(response.getOutputStream()); response.setContentType("application/x-zip-compressed"); //如果输出的是中文名的文件,在此处就要用URLEncoder.encode方法进行处理 response.setHeader("Content-Disposition", "attachment;filename=" + new String(zipFile.getName().getBytes(), "ISO8859-1")); toClient.write(buffer); toClient.flush(); toClient.close(); } catch (IOException ex) { ex.printStackTrace(); } finally{ // 删除临时文件 File zipFile = new File(System.getProperty("java.io.tmpdir") + "/" + filename + ".zip"); if (zipFile.exists()) { zipFile.delete(); } } } /** * 获取文件 * @param sourceFiles * @return */ private static List<File> getFilesByPath(List<String> sourceFiles) { List<File> files = new ArrayList<>(); sourceFiles.forEach(fileName -> { files.add(new File(fileName)); }); return files; } /** * 把接受的全部文件打成压缩包 * @param files * @param outputStream */ public static void zipFile (List files,ZipOutputStream outputStream) { int size = files.size(); for(int i = 0; i < size; i++) { File file = (File) files.get(i); zipFile(file, outputStream); } } /** * 根据输入的文件与输出流对文件进行打包 * @param inputFile * @param ouputStream */ public static void zipFile(File inputFile, ZipOutputStream ouputStream) { try { if(inputFile.exists()) { // 是文件的话直接压缩,否则循环内部文件压缩 if (inputFile.isFile()) { FileInputStream IN = new FileInputStream(inputFile); BufferedInputStream bins = new BufferedInputStream(IN, 512); ZipEntry entry = new ZipEntry(inputFile.getName()); ouputStream.putNextEntry(entry); // 向压缩文件中输出数据 int nNumber; byte[] buffer = new byte[512]; while ((nNumber = bins.read(buffer)) != -1) { ouputStream.write(buffer, 0, nNumber); } // 关闭创建的流对象 bins.close(); IN.close(); } else { try { File[] files = inputFile.listFiles(); for (int i = 0; i < files.length; i++) { zipFile(files[i], ouputStream); } } catch (Exception e) { e.printStackTrace(); } } } } catch (Exception e) { e.printStackTrace(); } } }