import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.commons.compress.archivers.zip.ZipFile;
/**
* ZIP格式文件工具类
* @author hw
*/
public class ZipUtil {
//缓存大小
private static final int BUFFER_SIZE = 1024*4;
/**
* 解压缩指定文件(默认使用UTF-8编码解析文件名)
* @param zipFile 压缩文件
* @param dir 解压路径(不存在自动创建,已存在文件将覆盖)
* @throws IOException
*/
public static void unzip(String zipFile, String dir) throws IOException {
unzip(zipFile, dir, "UTF-8");
}
/**
* 解压缩指定文件
* @param zipFile 压缩文件
* @param dir 解压路径(不存在会自动创建,已存在文件将覆盖)
* @param charset 文件名称编码格式
* @throws IOException
*/
public static void unzip(String zipFile, String dir, String charset) throws IOException{
ZipFile stream = new ZipFile(new File(zipFile), charset);
// 解压路径是否存在,不存在创建
File dirFile = new File(dir);
if (!dirFile.exists()) {
dirFile.mkdirs();
}
Enumeration<?> files = stream.getEntries();
try {
while (files.hasMoreElements()) {
ZipArchiveEntry entry = (ZipArchiveEntry) files.nextElement();
File file = new File(dir + System.getProperty("file.separator") + entry.getName());
// 节点是目录
if (entry.isDirectory()) {
file.mkdirs();
continue;
}
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
FileOutputStream outputStream = null;
InputStream inputStream = null;
try {
outputStream = new FileOutputStream(file);
inputStream = stream.getInputStream(entry);
byte[] buf = new byte[BUFFER_SIZE];
int length = 0;
while ((length=inputStream.read(buf,0,BUFFER_SIZE))!=-1) {
outputStream.write(buf, 0, length);
}
} catch (IOException e) {
throw e;
} finally {
if(inputStream!=null){
inputStream.close();
}
if(outputStream!=null){
outputStream.close();
}
}
}
} catch (IOException e) {
throw e;
} finally {
stream.close();
}
}
/**
* 压缩目录文件
* @param dir 要压缩的文件目录
* @param zipFile 输出的压缩文件
* @throws IOException
*/
public static void zip(String dir, String zipFile) throws IOException {
zip(dir,zipFile,"UTF-8");
}
/**
* 压缩文件
*
* @param dir 要压缩的文件目录
* @param zipFile 输出的压缩文件
* @param charset 中文文件名编码
* @throws IOException
*/
public static void zip(String dir, String zipFile,String charset) throws IOException {
File dirFile = new File(dir);
if(!dirFile.exists() || !dirFile.isDirectory()){
throw new IOException("不是一个有效的目录:"+dir);
}
Map<String, File> fileMap = new HashMap<String, File>();
zip(setFilePath(dirFile,fileMap,"."), zipFile, charset);
}
/**
* 获取目录下文件的相对路径
* @param dir 目录
* @param fileMap 设置路径和文件对应关系
* @param rootPath 相对路径
* @return
*/
private static Map<String,File> setFilePath(File dir,Map<String, File> fileMap,String rootPath){
for(File f : dir.listFiles()){
if(f.isFile()){
fileMap.put(rootPath+"/"+f.getName(), f);
}else{
setFilePath(f, fileMap, rootPath+"/"+f.getName());
}
}
return fileMap;
}
/**
* 压缩文件
* @param files 要压缩的文件
* @param zipFile 输出的压缩文件
* @throws IOException
*/
public static void zip(List<File> files, String zipFile) throws IOException {
zip(files, zipFile, "UTF-8");
}
/**
* 压缩文件
* @param files 要压缩的文件
* @param zipFile 输出的压缩文件
* @param charset 文件名编码
* @throws IOException
*/
public static void zip(List<File> files, String zipFile , String charset) throws IOException {
Map<String, File> fileMap = new HashMap<String, File>();
for (File file : files) {
fileMap.put(file.getName(),file);
}
zip(fileMap,zipFile,charset);
}
/**
* 压缩文件
* @param files 要压缩的文件(文件在压缩文件中的相对路径)
* @param zipFile 输出的压缩文件
* @param charset 文件名编码
* @throws IOException
* @throws IOException
*/
public static void zip(Map<String,File> files, String zipFile , String charset) throws IOException{
ZipArchiveOutputStream out = new ZipArchiveOutputStream(new File(zipFile));
// 设置编码,中文文件名乱码
out.setEncoding(charset);
for (String filePath : files.keySet()) {
File file = files.get(filePath);
BufferedInputStream in = null;
try {
in = new BufferedInputStream(new FileInputStream(file));
out.putArchiveEntry(new ZipArchiveEntry(file,filePath));
int count;
byte data[] = new byte[BUFFER_SIZE];
while ((count = in.read(data, 0, BUFFER_SIZE)) != -1) {
out.write(data, 0, count);
}
out.closeArchiveEntry();
} catch (IOException e) {
throw e;
} finally {
try {
out.close();
if(in!=null){
in.close();
}
} catch (IOException e) {
}
}
}
}
}