實現邏輯
1、使用java.util.zip.ZipOutputStream構造一個壓縮流(zip)
2、將一個或多個文件構造成對應的壓縮流的條目(java.util.zip.Entry)
3、將壓縮流輸出即可。
4、若是多個文件打包則需要考慮文件同名問題。
依賴
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
源碼
package com.zhicheng.utils;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
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.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ZipUitls {
private Logger logger = LoggerFactory.getLogger(ZipUitls.class);
/**
* 批量壓縮文件
* 1、一般獲取文件都是在該方法中直接下載,不會直接是使用map傳入
* @param fileIns
* @param fileName
* @return
* @throws IOException
*/
public static InputStream compress2ZipBatch(Map<File,InputStream> fileIns) throws IOException{
if(fileIns.isEmpty()) {
throw new IllegalArgumentException("the param fileIns can not be empty!");
}
//處理文件名相同情況
Map<String,Integer> fileNameMap = new HashMap<String,Integer>();
// 文件緩存輸出流
ByteArrayOutputStream byteCache = new ByteArrayOutputStream();
// 壓縮流
ZipOutputStream zipOutStream = new ZipOutputStream(byteCache);
try {
for(Entry<File,InputStream> entry:fileIns.entrySet()) {
addZipEntry(zipOutStream, entry.getValue(), dealSameFileName(fileNameMap,entry.getKey().getName()));
}
}finally {
IOUtils.closeQuietly(zipOutStream);
}
return new ByteArrayInputStream(byteCache.toByteArray());
}
/**
* 壓縮單個文件
* @param in
* @param fileName
* @return
* @throws IOException
*/
public static InputStream compress2Zip(InputStream in,String fileName) throws IOException {
// 文件輸出流
ByteArrayOutputStream byteCache = new ByteArrayOutputStream();
// 壓縮流
ZipOutputStream zipOutStream = new ZipOutputStream(byteCache);
addZipEntry(zipOutStream,in,fileName);
return new ByteArrayInputStream(byteCache.toByteArray());
}
//添加條目
private static void addZipEntry(ZipOutputStream zos, InputStream in, String fileName) throws IOException{
try {
zos.putNextEntry(new ZipEntry(fileName));
zos.write(IOUtils.toByteArray(in));
zos.closeEntry();
}finally {
IOUtils.closeQuietly(in);
}
}
/**
* 處理同一包中同名文件
* 相同的文件名後&後綴前遞增加(n)
* @param fileNameMap
* @param fileName
* @return
*/
private static String dealSameFileName(Map<String,Integer> fileNameMap,String fileName) {
String _fileName = fileName.substring(0,fileName.lastIndexOf("."));
String suffix = fileName.substring(fileName.lastIndexOf(".")+1);
if(fileNameMap.containsKey(fileName)) {
Integer size = fileNameMap.get(fileName);
fileNameMap.put(fileName, size.intValue()+1);
return _fileName+"("+size.intValue()+")."+suffix;
}else {
fileNameMap.put(fileName, 1);
return fileName;
}
}
/**
* 測試
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
File[] files = new File("D:\\Oss_file\\pdfTest").listFiles();
if(ArrayUtils.isNotEmpty(files)) {
Map<File,InputStream> insMap = new HashMap<File,InputStream>();
for(File file:files) {
if(file.isFile()) {
insMap.put(file,new FileInputStream(file));
}
}
OutputStream out = new FileOutputStream("D:\\Oss_file\\pdfTest\\test\\file.zip");
IOUtils.copy(compress2ZipBatch(insMap), out);
IOUtils.closeQuietly(out);
}
System.out.println("執行完成!");
}
}