Java压缩、解压缩、添加文件到压缩包工具类,解决文件名乱码、中文解压报错等问题。具体功能请查看源码。
package cn.elwy.common.util.io;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;
import org.apache.tools.zip.ZipOutputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import cn.elwy.common.util.ReflectUtil;
import cn.elwy.common.util.i18n.Msg;
public class ZipUtil {
private static Logger logger = LoggerFactory.getLogger(ZipUtil.class);
private static final String ENCODE = System.getProperty("sun.jnu.encoding");
private static final String ZIP = ".zip";
private static final int BUFFER_SIZE = 512000; // 500KB
/**
* 将一个文件或目录压缩成一个zip文件
* @param srcPath 文件或目录路径
* @param destPath 目标路径
* @throws IOException
*/
public static void compress(String srcPath, String destPath) throws IOException {
compress(new File(srcPath), new File(destPath), null, null);
}
/**
* 将一个文件或目录压缩成一个zip文件
* @param srcPath 文件或目录路径
* @param destPath 目标路径
* @param comment 压缩包注释
* @throws IOException
*/
public static void compress(String srcPath, String destPath, String comment) throws IOException {
compress(new File(srcPath), new File(destPath), comment, null);
}
/**
* 将一个文件或目录压缩成一个zip文件
* @param srcFile 文件或目录
* @param destFile 目标文件
* @param comment 压缩包注释
* @throws IOException
*/
public static void compress(File srcFile, File destFile, String comment) throws IOException {
compress(srcFile, destFile, comment, null);
}
/**
* 将一个文件或目录压缩成一个zip文件
* @param srcFile 文件或目录
* @param destFile 目标文件
* @param comment 压缩包注释
* @param filter 过滤文件(正则表达式)
* @throws IOException
*/
public static void compress(File srcFile, File destFile, String comment, List filter) throws IOException {
List fileList = new ArrayList();
fileList.add(srcFile);
compress(fileList, destFile, comment, filter, false);
}
/**
* 将一组文件或目录压缩成一个zip文件
* @param fileList 文件或目录列表
* @param destFile 目标文件
* @param comment 压缩包注释
* @param filter 过滤文件(正则表达式)
* @throws IOException
*/
public static void compress(List fileList, File destFile, String comment, List filter)
throws IOException {
compress(fileList, destFile, comment, filter, false);
}
/**
* 将一组文件或目录压缩成一个zip文件
* @param fileList 文件或目录列表
* @param destFile 目标文件
* @param comment 压缩包注释
* @param filter 过滤文件(正则表达式)
* @param ignoreError 忽略错误
* @throws IOException
*/
public static void compress(List fileList, File destFile, String comment, List filter,
boolean ignoreError) throws IOException {
if (destFile.isDirectory()) {
String name = destFile.getName() + ZIP;
destFile = new File(destFile, name);
if (filter == null) {
filter = new ArrayList();
}
filter.add(name);
}
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(destFile));
try {
zos.setEncoding(ENCODE);
for (File file : fileList) {
if (fileList.size() == 1) {
compress(zos, file, "", comment, filter, ignoreError);
} else {
compress(zos, file, file.getName(), comment, filter, ignoreError);
}
}
} finally {
ReflectUtil.close(zos);
}
}
/**
* 添加文件到压缩包中
* @param zipFile
* @param file
* @param entryPath
* @throws IOException
*/
public static void addFileToZip(File zipFile, File file, String entryPath) throws IOException {
addFileToZip(zipFile, new File[] { file }, new String[] { entryPath });
}
/**
* 添加文件到压缩包中
* @param zipFile
* @param files
* @param entryPaths
* @throws IOException
*/
public static void addFileToZip(File zipFile, File[] files, String[] entryPaths) throws IOException {
File tempFile = File.createTempFile(zipFile.getName(), null);
tempFile.delete();
boolean renameOk = zipFile.renameTo(tempFile);
if (!renameOk) {
throw new RuntimeException("could not rename the file " + zipFile.getAbsolutePath() + " to "
+ tempFile.getAbsolutePath());
}
addFileToZip(tempFile, zipFile, files, entryPaths);
}
/**
* 添加文件到压缩包中
* @param srcZip
* @param destZip
* @param files
* @param entryPaths
* @throws IOException
*/
public static void addFileToZip(File srcZip, File destZip, File[] files, String[] entryPaths) throws IOException {
byte[] buffer = new byte[BUFFER_SIZE];
ZipFile zipFile = new ZipFile(srcZip, ENCODE);
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(destZip));
try {
out.setEncoding(ENCODE);
Enumeration> e = zipFile.getEntries();
while (e.hasMoreElements()) {
ZipEntry entry = (ZipEntry) e.nextElement();
String name = entry.getName();
boolean notInFiles = true;
String entryName = "";
for (int i = 0; i < files.length; i++) {
File file = files[i];
if (entryPaths != null && i < entryPaths.length) {
entryName = entryPaths[i];
}
if ((entryName + "/" + file.getName()).equals(name)) {
notInFiles = false;
break;
}
}
if (notInFiles) {
out.putNextEntry(new ZipEntry(name));
InputStream is = zipFile.getInputStream(entry);
int length = 0;
while ((length = is.read(buffer, 0, BUFFER_SIZE)) != -1) {
out.write(buffer, 0, length);
}
}
}
String entryName = "";
for (int i = 0; i < files.length; i++) {
File file = files[i];
if (entryPaths != null && i < entryPaths.length) {
entryName = entryPaths[i];
}
if (file.isDirectory()) {
compress(out, file, entryName, "", null, false);
} else {
compress(out, file, entryName + "/" + file.getName(), "", null, false);
}
}
} finally {
zipFile.close();
out.close();
}
}
/**
* 将一组文件或目录压缩到一个Zip输出流中
* @param out zip输出流
* @param srcFile 文件或目录
* @param name 压缩包中的名称
* @param comment 压缩包注释
* @param filter 过滤文件(正则表达式)
* @param ignoreError 忽略错误
* @throws IOException
*/
public static void compress(ZipOutputStream out, File srcFile, String name, String comment, List filter,
boolean ignoreError) throws IOException {
if (srcFile.exists() == false) {
throw new IOException(srcFile.getAbsolutePath() + Msg.E_FILE_NOT_EXISTS);
}
try {
if (srcFile.isDirectory()) {
File[] files = srcFile.listFiles();
name = name.length() == 0 ? "" : name + "/";
if (!isFilter(name, filter) && name.length() != 0) {
out.putNextEntry(new ZipEntry(name));
}
for (File file : files) {
compress(out, file, name + file.getName(), comment, filter, ignoreError);
}
} else {
if (!isFilter(name, filter)) {
name = name.length() == 0 ? srcFile.getName() : name;
ZipEntry zipEntry = new ZipEntry(name);
zipEntry.setComment(comment);
out.putNextEntry(zipEntry);
FileInputStream in = null;
try {
in = new FileInputStream(srcFile);
int length = 0;
byte[] buffer = new byte[BUFFER_SIZE];
while ((length = in.read(buffer, 0, BUFFER_SIZE)) != -1) {
out.write(buffer, 0, length);
}
} finally {
ReflectUtil.close(in);
}
}
}
} catch (IOException e) {
if (ignoreError) {
logger.warn("compress zip ignore error: ");
logger.warn(e.getMessage(), e);
} else {
throw e;
}
}
}
/**
* 指定的名称是否被过滤
* @param base
* @param filter 过滤列表(正则表达式)
* @return
*/
private static boolean isFilter(String base, List filter) {
if (filter != null && !filter.isEmpty()) {
for (int i = 0; i < filter.size(); i++) {
Pattern pat = Pattern.compile(filter.get(i));
Matcher mat = pat.matcher(base);
if (mat.find()) {
return true;
}
}
}
return false;
}
/**
* 将一个zip文件解压到一个目录
* @param srcPath 压缩包路径
* @param destDir 解压位置
* @param deleteFile 是否删除
* @throws IOException
*/
public static void uncompress(String srcPath, String destDir, boolean deleteFile) throws IOException {
uncompress(new File(srcPath), new File(destDir), deleteFile);
}
/**
* 将一个zip文件解压到一个目录
* @param srcFile 压缩包文件
* @param destDir 解压位置
* @param deleteFile 是否删除
* @throws IOException
*/
public static void uncompress(File srcFile, File destDir, boolean deleteFile) throws IOException {
if (!srcFile.exists()) {
throw new IOException(srcFile.getAbsolutePath() + Msg.E_FILE_NOT_EXISTS);
}
if (destDir.isFile()) {
throw new IOException(Msg.E_ZIPUTIL_UNZIPPATHCANNOTFILE);
}
ZipFile zipFile = null;
try {
zipFile = new ZipFile(srcFile, ENCODE);
Enumeration> e = zipFile.getEntries();
while (e.hasMoreElements()) {
ZipEntry zipEntry = (ZipEntry) e.nextElement();
if (zipEntry.isDirectory()) {
String name = zipEntry.getName();
name = name.substring(0, name.length() - 1);
File f = new File(destDir, name);
f.mkdirs();
} else {
File f = new File(destDir, zipEntry.getName());
f.getParentFile().mkdirs();
f.createNewFile();
InputStream is = null;
FileOutputStream fos = null;
try {
is = zipFile.getInputStream(zipEntry);
fos = new FileOutputStream(f);
int length = 0;
byte[] buffer = new byte[BUFFER_SIZE];
while ((length = is.read(buffer, 0, BUFFER_SIZE)) != -1) {
fos.write(buffer, 0, length);
}
} finally {
ReflectUtil.close(fos);
}
}
}
} finally {
ReflectUtil.close(zipFile);
}
if (deleteFile) {
srcFile.deleteOnExit();
}
}
/**
* 读取压缩包的注释
* @param filePath
* @return
* @throws IOException
*/
public static String getZipComment(String filePath) throws IOException {
ZipFile zipFile = null;
try {
zipFile = new ZipFile(filePath, ENCODE);
Enumeration> e = zipFile.getEntries();
String comment = "";
while (e.hasMoreElements()) {
ZipEntry ze = (ZipEntry) e.nextElement();
comment = ze.getComment();
if (comment != null && !comment.equals("") && !comment.equals("null")) {
break;
}
}
return comment;
} finally {
ReflectUtil.close(zipFile);
}
}
// 功能和效率与compress方法类似
// /**
// * 将一个文件或目录压缩成一个zip文件
// * @param srcPath 源文件路径
// * @param destPath 目标路径
// * @throws IOException
// */
// public static void zip(String srcPath, String destPath) throws IOException {
// zip(srcPath, destPath, null, null);
// }
//
// /**
// * 将一个文件或目录压缩成一个zip文件
// * @param srcPath 源文件路径
// * @param destPath 目标路径
// * @param include 包含规则
// * @param exclude 排序规则
// * @throws IOException
// */
// public static void zip(String srcPath, String destPath, String include, String exclude) throws IOException {
// zip(new File(srcPath), new File(destPath), include, exclude);
// }
//
// /**
// * 将一个文件或目录压缩成一个zip文件
// * @param srcFile 源文件
// * @param destFile 目标文件
// * @throws IOException
// */
// public static void zip(File srcFile, File destFile) throws IOException {
// zip(srcFile, destFile, null, null);
// }
//
// /**
// * 将一个文件或目录压缩成一个zip文件
// * @param srcFile 源文件
// * @param destFile 目标文件
// * @param include 包含规则
// * @param exclude 排序规则
// * @throws IOException
// */
// public static void zip(File srcFile, File destFile, String include, String exclude) throws IOException {
// if (!srcFile.exists()) {
// throw new IOException(srcFile.getAbsolutePath() + Msg.E_FILE_NOT_EXISTS);
// }
// if (destFile.isDirectory()) {
// String name = destFile.getName() + ZIP;
// destFile = new File(destFile, name);
// }
// Project project = new Project();
// FileSet fileSet = new FileSet();
// fileSet.setProject(project);
// // 判断是目录还是文件
// if (srcFile.isDirectory()) {
// fileSet.setDir(srcFile);
// } else {
// fileSet.setFile(srcFile);
// }
// if (AssertUtil.isNotEmpty(include)) {
// fileSet.setIncludes(include);// 包括哪些文件或文件夹
// }
// if (AssertUtil.isNotEmpty(exclude)) {
// fileSet.setExcludes(exclude); // 排除哪些文件或文件夹
// }
//
// Zip zip = new Zip();
// zip.setProject(project);
// zip.setDestFile(destFile);
// zip.addFileset(fileSet);
// zip.setEncoding(ENCODE);
//
// zip.execute();
// }
//
// /**
// * 解压缩
// * @param srcPath 压缩包
// * @param destDir 解压位置
// * @throws IOException
// */
// public static void unzip(String srcPath, String destDir) throws IOException {
// unzip(new File(srcPath), new File(destDir));
// }
//
// /**
// * 解压缩
// * @param srcFile 压缩包
// * @param destDir 解压位置
// * @throws IOException
// */
// public static void unzip(File srcFile, File destDir) throws IOException {
// if (!srcFile.exists()) {
// throw new IOException(srcFile.getAbsolutePath() + Msg.E_FILE_NOT_EXISTS);
// }
// if (destDir.isFile()) {
// throw new IOException(Msg.E_ZIPUTIL_UNZIPPATHCANNOTFILE);
// }
// Project project = new Project();
// Expand expand = new Expand();
// expand.setProject(project);
// expand.setTaskType("unzip");
// expand.setTaskName("unzip");
// expand.setEncoding(ENCODE);
//
// expand.setSrc(srcFile);
// expand.setDest(destDir);
//
// expand.execute();
// }
}