使用Java實現(xiàn)壓縮文件夾并打包下載
工具類如下
打包下載方法:exportZip(支持整個文件夾或單文件一起)
注意:前端發(fā)送請求不能用ajax,form表單提交可以,location.href也可以,window.open也可以,總之就ajax請求就是不行
示例代碼
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 下載時的文件名稱
* // * @param postfix 下載時的文件后綴 .zip/.rar
*/
public static void exportZip(HttpServletResponse response, String sourceFilePath, String fileName) {
// 默認(rèn)文件名以時間戳作為前綴
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();
}
/***
* 對文件下的文件處理
*/
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();
//將文件夾添加到下一級打包目錄
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實體,并添加進(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)對壓縮包里的每一個文件進(jìn)行解壓
while (entries.hasMoreElements()) {
entry = entries.nextElement();
// 構(gòu)建壓縮包中一個文件解壓后保存的文件全路徑
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()) {
// 檢測文件是否允許刪除,如果不允許刪除,將會拋出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)閉掉,不然在同一個線程,你想解壓到臨時路徑之后,再去刪除掉這些臨時數(shù)據(jù),那么就刪除不了
}
}
}
到此這篇關(guān)于使用Java實現(xiàn)壓縮文件夾并打包下載的文章就介紹到這了,更多相關(guān)Java壓縮文件夾內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java隊列實現(xiàn)方法(順序隊列,鏈?zhǔn)疥犃?循環(huán)隊列)
下面小編就為大家分享一篇java隊列實現(xiàn)方法(順序隊列,鏈?zhǔn)疥犃?循環(huán)隊列),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2017-12-12
No ‘Access-Control-Allow-Origin‘ header is&nb
這篇文章主要介紹了No ‘Access-Control-Allow-Origin‘ header is present跨域及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-02-02
解決IDEA集成Docker插件后出現(xiàn)日志亂碼的問題
這篇文章主要介紹了解決IDEA集成Docker插件后出現(xiàn)日志亂碼的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-11-11
win11?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

