使用Java實(shí)現(xiàn)壓縮文件夾并打包下載
工具類如下
打包下載方法:exportZip(支持整個(gè)文件夾或單文件一起)
注意:前端發(fā)送請(qǐng)求不能用ajax,form表單提交可以,location.href也可以,window.open也可以,總之就ajax請(qǐng)求就是不行
示例代碼
import com.leatop.common.utils.StringUtils; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.servlet.http.HttpServletResponse; import java.io.*; import java.net.URLEncoder; import java.nio.channels.FileChannel; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Enumeration; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipOutputStream; public class FileToZipUtils { // 日志 private static Logger log = LoggerFactory.getLogger(FileToZipUtils.class); // 創(chuàng)建文件夾 public static String CreateFile(String dir) { File file = new File(dir); if (!file.exists()) { //創(chuàng)建文件夾 boolean mkdir = file.mkdir(); } else { } return dir; } // 復(fù)制文件 public static void copyFile(File source, File dest) throws IOException { FileChannel inputChannel = null; FileChannel outputChannel = null; try { inputChannel = new FileInputStream(source).getChannel(); outputChannel = new FileOutputStream(dest).getChannel(); outputChannel.transferFrom(inputChannel, 0, inputChannel.size()); } finally { inputChannel.close(); outputChannel.close(); } } // 刪除文件 public void delFile(File file) { File[] listFiles = file.listFiles(); if (listFiles != null) { for (File f : listFiles) { if (f.isDirectory()) { delFile(f); } else { f.delete(); } } } file.delete(); } /** * 通過遞歸逐層刪除文件信息 * * @param filePath */ public static void deleteFileByIO(String filePath) { File file = new File(filePath); File[] list = file.listFiles(); if (list != null) { for (File temp : list) { deleteFileByIO(temp.getAbsolutePath()); } } file.delete(); } /** * 將指定路徑下的所有文件打包zip導(dǎo)出 * * @param response HttpServletResponse * @param sourceFilePath 要打包的路徑 * @param fileName 下載時(shí)的文件名稱 * // * @param postfix 下載時(shí)的文件后綴 .zip/.rar */ public static void exportZip(HttpServletResponse response, String sourceFilePath, String fileName) { // 默認(rèn)文件名以時(shí)間戳作為前綴 SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); String downloadName = sdf.format(new Date()) + fileName; // 將文件進(jìn)行打包下載 try { OutputStream os = response.getOutputStream(); // 接收壓縮包字節(jié) byte[] data = createZip(sourceFilePath); response.reset(); response.setCharacterEncoding("UTF-8"); response.addHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Access-Control-Expose-Headers", "*"); // 下載文件名亂碼問題 response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8")); //response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName); response.addHeader("Content-Length", "" + data.length); response.setContentType("application/octet-stream;charset=UTF-8"); IOUtils.write(data, os); os.flush(); os.close(); } catch (Exception e) { e.printStackTrace(); } } /*** * 壓縮文件變成zip輸出流 */ public static byte[] createZip(String srcSource) throws Exception { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); ZipOutputStream zip = new ZipOutputStream(outputStream); //將目標(biāo)文件打包成zip導(dǎo)出 File file = new File(srcSource); createAllFile(zip, file, ""); IOUtils.closeQuietly(zip); return outputStream.toByteArray(); } /*** * 對(duì)文件下的文件處理 */ public static void createAllFile(ZipOutputStream zip, File file, String dir) throws Exception { //如果當(dāng)前的是文件夾,則進(jìn)行進(jìn)一步處理 if (file.isDirectory()) { //得到文件列表信息 File[] files = file.listFiles(); //將文件夾添加到下一級(jí)打包目錄 zip.putNextEntry(new ZipEntry(dir + "/")); dir = dir.length() == 0 ? "" : dir + "/"; //循環(huán)將文件夾中的文件打包 for (int i = 0; i < files.length; i++) { createAllFile(zip, files[i], dir + files[i].getName()); //遞歸處理 } } else { //當(dāng)前的是文件,打包處理 //文件輸入流 BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file)); ZipEntry entry = new ZipEntry(dir); zip.putNextEntry(entry); zip.write(FileUtils.readFileToByteArray(file)); IOUtils.closeQuietly(bis); zip.flush(); zip.closeEntry(); } } /** * 將存放在sourceFilePath目錄下的源文件,打包成fileName名稱的zip文件,并存放到zipFilePath路徑下 * * @param sourceFilePath :待壓縮的文件路徑 * @param zipFilePath :壓縮后存放路徑 * @param fileName :壓縮后文件的名稱 * @return */ public static boolean fileToZip(String sourceFilePath, String zipFilePath, String fileName) { boolean flag = false; File sourceFile = new File(sourceFilePath); FileInputStream fis = null; BufferedInputStream bis = null; FileOutputStream fos = null; ZipOutputStream zos = null; if (sourceFile.exists() == false) { log.info("待壓縮的文件目錄:" + sourceFilePath + "不存在."); } else { try { File zipFile = new File(zipFilePath + "/" + fileName + ".zip"); if (zipFile.exists()) { log.info(zipFilePath + "目錄下存在名字為:" + fileName + ".zip" + "打包文件."); } else { File[] sourceFiles = sourceFile.listFiles(); if (null == sourceFiles || sourceFiles.length < 1) { log.info("待壓縮的文件目錄:" + sourceFilePath + "里面不存在文件,無需壓縮."); } else { fos = new FileOutputStream(zipFile); zos = new ZipOutputStream(new BufferedOutputStream(fos)); byte[] bufs = new byte[1024 * 10]; for (int i = 0; i < sourceFiles.length; i++) { // 創(chuàng)建ZIP實(shí)體,并添加進(jìn)壓縮包 ZipEntry zipEntry = new ZipEntry(sourceFiles[i].getName()); zos.putNextEntry(zipEntry); // 讀取待壓縮的文件并寫進(jìn)壓縮包里 fis = new FileInputStream(sourceFiles[i]); bis = new BufferedInputStream(fis, 1024 * 10); int read = 0; while ((read = bis.read(bufs, 0, 1024 * 10)) != -1) { zos.write(bufs, 0, read); } } flag = true; } } } catch (FileNotFoundException e) { e.printStackTrace(); throw new RuntimeException(e); } catch (IOException e) { e.printStackTrace(); throw new RuntimeException(e); } finally { // 關(guān)閉流 try { if (null != bis) bis.close(); if (null != zos) zos.close(); } catch (IOException e) { e.printStackTrace(); throw new RuntimeException(e); } } } return flag; } /** * 解壓縮zip包 * * @param zipFilePath 需要解壓的zip文件的全路徑 * @param unzipFilePath 解壓后的文件保存的路徑 * @param includeZipFileName 解壓后的文件保存的路徑是否包含壓縮文件的文件名。true-包含;false-不包含 */ @SuppressWarnings("unchecked") public static void unzip(String zipFilePath, String unzipFilePath, boolean includeZipFileName) throws Exception { if (StringUtils.isNotBlank(zipFilePath) || StringUtils.isNotBlank(unzipFilePath)) { File zipFile = new File(zipFilePath); // 如果解壓后的文件保存路徑包含壓縮文件的文件名,則追加該文件名到解壓路徑 if (includeZipFileName) { String fileName = zipFile.getName(); if (StringUtils.isNotEmpty(fileName)) { fileName = fileName.substring(0, fileName.lastIndexOf(".")); } unzipFilePath = unzipFilePath + File.separator + fileName; } // 創(chuàng)建解壓縮文件保存的路徑 File unzipFileDir = new File(unzipFilePath); if (!unzipFileDir.exists() || !unzipFileDir.isDirectory()) { unzipFileDir.mkdirs(); } // 開始解壓 ZipEntry entry = null; String entryFilePath = null, entryDirPath = null; File entryFile = null, entryDir = null; int index = 0, count = 0, bufferSize = 1024; byte[] buffer = new byte[bufferSize]; BufferedInputStream bis = null; BufferedOutputStream bos = null; ZipFile zip = new ZipFile(zipFile); Enumeration<ZipEntry> entries = (Enumeration<ZipEntry>) zip.entries(); // 循環(huán)對(duì)壓縮包里的每一個(gè)文件進(jìn)行解壓 while (entries.hasMoreElements()) { entry = entries.nextElement(); // 構(gòu)建壓縮包中一個(gè)文件解壓后保存的文件全路徑 entryFilePath = unzipFilePath + File.separator + entry.getName(); // 構(gòu)建解壓后保存的文件夾路徑 index = entryFilePath.lastIndexOf(File.separator); if (index != -1) { entryDirPath = entryFilePath.substring(0, index); } else { entryDirPath = ""; } entryDir = new File(entryDirPath); // 如果文件夾路徑不存在,則創(chuàng)建文件夾 if (!entryDir.exists() || !entryDir.isDirectory()) { entryDir.mkdirs(); } // 創(chuàng)建解壓文件 entryFile = new File(entryFilePath); if (entryFile.exists()) { // 檢測(cè)文件是否允許刪除,如果不允許刪除,將會(huì)拋出SecurityException SecurityManager securityManager = new SecurityManager(); securityManager.checkDelete(entryFilePath); // 刪除已存在的目標(biāo)文件 entryFile.delete(); } // 寫入文件 bos = new BufferedOutputStream(new FileOutputStream(entryFile)); bis = new BufferedInputStream(zip.getInputStream(entry)); while ((count = bis.read(buffer, 0, bufferSize)) != -1) { bos.write(buffer, 0, count); } bos.flush(); bos.close(); } zip.close();// 切記一定要關(guān)閉掉,不然在同一個(gè)線程,你想解壓到臨時(shí)路徑之后,再去刪除掉這些臨時(shí)數(shù)據(jù),那么就刪除不了 } } }
到此這篇關(guān)于使用Java實(shí)現(xiàn)壓縮文件夾并打包下載的文章就介紹到這了,更多相關(guān)Java壓縮文件夾內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java之SpringCloud nocos注冊(cè)中心講解
這篇文章主要介紹了Java之SpringCloud nocos注冊(cè)中心講解,本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-08-08java隊(duì)列實(shí)現(xiàn)方法(順序隊(duì)列,鏈?zhǔn)疥?duì)列,循環(huán)隊(duì)列)
下面小編就為大家分享一篇java隊(duì)列實(shí)現(xiàn)方法(順序隊(duì)列,鏈?zhǔn)疥?duì)列,循環(huán)隊(duì)列),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2017-12-12No ‘Access-Control-Allow-Origin‘ header is&nb
這篇文章主要介紹了No ‘Access-Control-Allow-Origin‘ header is present跨域及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02解決IDEA集成Docker插件后出現(xiàn)日志亂碼的問題
這篇文章主要介紹了解決IDEA集成Docker插件后出現(xiàn)日志亂碼的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-11-11win11?idea?shift+F6快捷鍵失效問題解決方案
這篇文章主要介紹了win11?idea?shift+F6快捷鍵失效問題,本文給大家分享最新解決方案,需要的朋友可以參考下2023-08-08探索jedis連接池預(yù)熱優(yōu)化高并發(fā)
這篇文章主要為大家介紹了jedis連接池預(yù)熱優(yōu)化高并發(fā)深入探索示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10