经常用到的生成可下载的zip压缩包的工具类和调用示例
import com.xdja.pki.core.exception.ServiceException;
import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.zip.Zip64Mode;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.poi.util.IOUtils;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
* zip包打包工具类
*
*/
public class ZipUtils {
/**
* 创建zip包
* @param srcSource
* @param fileName 如果是单独一个文件 该变量为文件名
* @return
* @throws Exception
*/
public static byte[] createZipByFile(String srcSource, String fileName) throws Exception {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ZipOutputStream zip = new ZipOutputStream(outputStream);
//将目标文件打包成zip导出
File file = new File(srcSource);
make(zip,file,fileName);
IOUtils.closeQuietly(zip);
return outputStream.toByteArray();
}
public static void make(ZipOutputStream zip, File file, String dir) throws Exception {
//如果当前的是文件夹,则进行进一步处理
if (file.isDirectory()) {
//得到文件列表信息
File[] files = file.listFiles();
//将文件夹添加到下一级打包目录
/*
do 0320 bug 77632 去掉多层文件夹
zip.putNextEntry(new ZipEntry( dir + "/"));
dir = dir.length() == 0 ? "" : dir + "/";
*/
//循环将文件夹中的文件打包
for (int i = 0; i < files.length; i++) {
make(zip, files[i], files[i].getName()); //递归处理
}
} else { //当前的是文件,打包处理
//文件输入流
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
ZipEntry entry = new ZipEntry(dir);
zip.putNextEntry(entry);
zip.write(FileUtils.readByBinary(file.getPath()));
IOUtils.closeQuietly(bis);
zip.flush();
zip.closeEntry();
}
}
/**
* 生成zip压缩包保存
* @param bytes
* @param strZipName
* @throws Exception
*/
public static void generateZipFile(List<Map<String,Object>> bytes,String strZipName) throws Exception {
ZipOutputStream out = null;
//压缩文件路径
File desFile = new File(strZipName);
if(!desFile.exists()) {
desFile.getParentFile().mkdirs();
desFile.createNewFile();
}
ZipArchiveOutputStream zous = new ZipArchiveOutputStream(desFile);
//防止中文乱码
if(zous instanceof ZipArchiveOutputStream) {
zous.setEncoding("GBK");
}
try {
zous.setUseZip64(Zip64Mode.AsNeeded);
for (int i=0;i<bytes.size();i++) {
String name = (String) bytes.get(i).get("name");
String suffix = (String) bytes.get(i).get("suffix");
// 前面几个参数只是为了命名文件,这个by才是二进制文件,是byte[]的形式
byte[] by = (byte[]) bytes.get(i).get("buffer");
String filename = name+"."+suffix;
ArchiveEntry entry = new ZipArchiveEntry(filename);
zous.putArchiveEntry(entry);
zous.write(by);
zous.closeArchiveEntry();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
zous.close();
}
}
/**
* 生成zip文件的的字节流形式
* @param bytes
* @return
* @throws Exception
*/
public static byte[] generateZipByte(List<Map<String,Object>> bytes) throws Exception {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ZipOutputStream out = null;
try {
out = new ZipOutputStream(outputStream);
for (int i=0;i<bytes.size();i++) {
String name = (String) bytes.get(i).get("name");
String suffix = (String) bytes.get(i).get("suffix");
// 前面几个参数只是为了命名文件,这个by才是二进制文件,是byte[]的形式
byte[] by = (byte[]) bytes.get(i).get("buffer");
String filename = name+"."+suffix;
ArchiveEntry entry = new ZipArchiveEntry(filename);
out.putNextEntry(new ZipEntry(name+"."+suffix));
out.write(by);
out.closeEntry();
out.flush();
}
} catch (Exception e) {
throw new ServiceException(e);
} finally {
if (out != null) {
out.close();
}
}
return outputStream.toByteArray();
}
/**
* 读取文件二进制内容
*
* @param path
* @return
* @throws IOException
*/
public static byte[] readByBinary(String path) {
InputStream inputStream = null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
inputStream = new FileInputStream(path);
int c = 0;
byte[] bytes = new byte[1024];
while ((c = inputStream.read(bytes)) != -1) {
baos.write(bytes, 0, c);
}
inputStream.close();
} catch (Exception e) {
throw new RuntimeException("读取文件二进制内容异常" + e.getMessage(), e);
}
return baos.toByteArray();
}
public static void main(String[] args) {
List<Map<String,Object>> list = new ArrayList<>();
Map<String,Object> signMap = new HashMap<>();
signMap.put("name","signCert");
signMap.put("suffix","cer");
byte[] signByte = readByBinary("E:\\home\\sign.cer");
signMap.put("buffer",signByte);
list.add(signMap);
Map<String,Object> encMap = new HashMap<>();
encMap.put("name","encCert");
encMap.put("suffix","cer");
byte[] encByte = readByBinary("E:\\home\\enc.cer");
encMap.put("buffer",encByte);
list.add(encMap);
try {
byte[] bytes = ZipUtils.generateZipByte(list);
} catch (Exception e) {
e.printStackTrace();
}
}
}
@RequestMapping(value = "/v1/download/{applyNo}", method = RequestMethod.GET)
public Object downloadUserCert(@PathVariable String applyNo, HttpServletResponse resp){
try {
String zipPath = "/home/file"+ applyNo;
String fileName = applyNo +".zip";
byte[] data = ZipUtils.createZipByFile(zipPath, fileName);
resp.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
resp.setCharacterEncoding("UTF-8");
resp.setHeader("Content-Disposition", "attachment; filename=" + fileName);
OutputStream out = resp.getOutputStream();
IOUtils.write(data, out);
out.flush();
out.close();
} catch (Exception e) {
logger.error("导出zip压缩包失败,原因:{}", e.getMessage());
return ErrorEnum.MAKE_ZIP_FILE_EXCEPTION.resp(resp);
}
return null;
}