壓縮、解壓縮工具類
package zj.compress.util;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.apache.commons.io.FilenameUtils;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Expand;
import de.innosystec.unrar.Archive;
import de.innosystec.unrar.rarfile.FileHeader;
import zj.check.util.CheckUtil;
import zj.common.KV;
import zj.common.exception.ServiceException;
import zj.compress.bean.CompressAttr;
import zj.compress.bean.Enums;
import zj.compress.bean.UnCompress;
import zj.io.util.FileUtil;
import zj.java.util.JavaUtil;
/**
* 壓縮、解壓縮工具類
* @version 1.00 (2011.12.02)
* @author SHNKCS 張軍 {@link <a target=_blank href="http://www.shanghaijiadun.com">上海加盾信息科技有限公司</a> <a target=_blank href="http://www.dlhighland.cn">張軍個人網站</a> <a target=_blank href="http://user.qzone.qq.com/360901061/">張軍QQ空間</a>}
*/
public class UnCompressUtil implements Serializable {
// private static Logger logger = Logger.getLogger(Compress.class);
/**
*
*/
private static final long serialVersionUID = 1L;
/**
* 獲取zip單個文件信息及內容
*
* @param zipFile
* 壓縮文件
* @return <文件名,內容byte[]>
*/
public static KV<String, byte[]> zipOnlyFile(File zipFile) {
ZipInputStream zipInputStream = null;
ByteArrayOutputStream bout = null;
ZipEntry zipEntry = null;
try {
// logger.info("開始解壓文件");
bout = new ByteArrayOutputStream();
// 獲取zip文件流
zipInputStream = new ZipInputStream(new FileInputStream(zipFile));
// 獲取壓縮文件
zipEntry = zipInputStream.getNextEntry();
byte[] buffer = new byte[1024];
int len = -1;
while ((len = zipInputStream.read(buffer)) != -1) {
bout.write(buffer, 0, len);
}
bout.flush();
// 解壓內容
byte[] extraData = bout.toByteArray();
// 壓縮包內的文件名
String zipEntryFileName = zipEntry.getName();
return KV.with(zipEntryFileName, extraData);
} catch (Exception e) {
throw new ServiceException(e);
} finally {
if (zipInputStream != null) {
try {
zipInputStream.closeEntry();
} catch (Exception e2) {
}
try {
zipInputStream.close();
} catch (Exception e) {
}
}
if (bout != null) {
try {
bout.close();
} catch (Exception e) {
}
}
}
}
/**
* 解壓zip格式壓縮包 對應的是ant.jar
*
* @param compress
* 壓縮對象
* @throws Exception
*/
public static void unzip(UnCompress compress) {
Project p = new Project();
Expand e = new Expand();
e.setProject(p);
e.setSrc(new File(compress.srcPath));
String overFlg = compress.overWrite;
e.setOverwrite(Enums.OverWrite.OVER.getValue().equals(overFlg) ? true : false);
e.setDest(new File(compress.descPath));
/*
* ant下的zip工具默認壓縮編碼為UTF-8編碼, 而winRAR軟件壓縮是用的windows默認的GBK或者GB2312編碼 所以解壓縮時要制定編碼格式
*/
e.setEncoding(compress.encoding);
e.execute();
}
/**
* 解壓rar格式壓縮包。 對應的是java-unrar-0.3.jar,但是java-unrar-0.3.jar又會用到commons-logging-1.1.1.jar
*
* @param compress
* 壓縮對象
* @throws Exception
*/
public static boolean unrarwin(UnCompress compress) {
try {
File srcFile = new File(compress.srcPath);
if (!srcFile.exists()) {
return false;
}
File destFile = new File(compress.descPath);
if (!destFile.exists()) {
destFile.mkdirs();
}
// 服務器需要安裝winrar
String winrarPath = compress.unrarPath;
if (CheckUtil.isNull(winrarPath)) {
winrarPath = "C:/Program Files/WinRAR/UnRAR.exe";
}
String cmd = winrarPath + " x " + srcFile.getAbsolutePath() + " " + destFile.getAbsolutePath();
Process proc = Runtime.getRuntime().exec(cmd);
if (proc.waitFor() != 0) {
if (proc.exitValue() == 0) {
return false;
}
} else {
}
return true;
} catch (Exception e) {
throw new ServiceException(e);
}
}
/**
* 解壓rar格式壓縮包。 對應的是java-unrar-0.3.jar,但是java-unrar-0.3.jar又會用到commons-logging-1.1.1.jar
*
* @param compress
* 壓縮對象
* @throws Exception
*/
public static void unrar(UnCompress compress) {
Archive arc = null;
BufferedOutputStream bos = null;
try {
arc = new Archive(new File(compress.srcPath));
FileHeader fh = arc.nextFileHeader();
// 設置壓縮文件里內容具體信息
List<CompressAttr> attrs = compress.compressAttrs;
while (fh != null) {
// 1 根據不同的操作系統拿到相應的 destDirName 和 destFileName
String compressFileName = JavaUtil.trim(fh.getFileNameString());
// 設置目標文件/文件夾路徑
String descPath = compress.descPath + FileUtil.changePathSeparator(compressFileName);
long length = fh.getFullUnpackSize();
// //("目標文件路徑:【" + descPath + "】壓縮文件路徑:【" + compressFileName + "】壓縮文件大小:【" + length + "】");
// 設置壓縮文件里內容具體信息
CompressAttr attr = new CompressAttr();
attrs.add(attr);
attr.descPath = compressFileName;
attr.length = length;
attr.directory = fh.isDirectory();
// 取得文件名
String[] compressFileNames = FileUtil.getFileNameExtension(compressFileName);
// 文件名
attr.fileName = compressFileNames[1] + compressFileNames[2];
if (fh.isDirectory()) {
} else {
if (CheckUtil.isNotNull(compress.descPath)) {
String[] descPaths = FileUtil.getFileNameExtension(descPath);
File descFile = new File(descPath);
if (Enums.OverWrite.OVER.getValue().equals(compress.overWrite)) {
// 覆蓋
// //("【" + descPath + "】文件重名,系統自動覆蓋此文件");
} else {
if (descFile.exists()) {
if (Enums.OverWrite.NO_OVER.getValue().equals(compress.overWrite)) {
// //("【" + descPath + "】文件重名,系統自動過慮此文件");
fh = arc.nextFileHeader();
continue;
} else {
String newPath = descPaths[0] + descPaths[1] + JavaUtil.getUUID() + descPaths[2];
// //("【" + descPath + "】文件重名,系統自動重新命名:【" + newPath + "】");
descFile = new File(newPath);
}
}
}
// 2創建文件夾
File dir = new File(descPaths[0]);
if (!dir.exists() || !dir.isDirectory()) {
dir.mkdirs();
}
// 3解壓縮文件
FileOutputStream fos = new FileOutputStream(descFile);
bos = new BufferedOutputStream(fos);
arc.extractFile(fh, fos);
}
}
fh = arc.nextFileHeader();
}
} catch (Exception e) {
throw new ServiceException(e);
} finally {
if (arc != null) {
try {
arc.close();
arc = null;
} catch (Exception e) {
}
}
if (bos != null) {
try {
bos.close();
bos = null;
} catch (Exception e) {
}
}
}
}
/**
* 解壓縮rar,zip
*
* @param compress
* 壓縮對象
* @throws Exception
*/
public static void setCompress(UnCompress compress) {
try {
/** 支持的文件擴展名 **/
String srcType = FilenameUtils.getExtension(compress.srcPath);
// 保證文件夾路徑最后是"/"或者"\"
if (CheckUtil.isNull(compress.descPath)) {
compress.descPath = "";
// //("壓縮文件內容沒有設置解壓目錄,因此系統將壓縮文件內容讀取至內存中");
} else {
compress.descPath = FileUtil.changePathSeparator(compress.descPath);
if (!compress.descPath.endsWith(File.separator)) {
compress.descPath = compress.descPath + File.separator;
}
}
// 根據類型,進行相應的解壓縮
if (Enums.FileExtension.ZIP.getValue().equalsIgnoreCase(srcType)) {
unzip(compress);
} else if (Enums.FileExtension.RAR.getValue().equalsIgnoreCase(srcType)) {
// unrar(compress);
unrarwin(compress);
} else {
// //("只支持zip和rar格式的壓縮包!");
List<String> fes = new ArrayList<String>();
for (Enums.FileExtension fe : Enums.FileExtension.values()) {
fes.add(fe.getValue());
}
throw new ServiceException("只支持[" + Arrays.toString(fes.toArray()) + "]格式的壓縮包!");
}
} catch (Exception e) {
throw new ServiceException(e);
}
}
}壓縮文件
package zj.compress.bean;
import java.io.Serializable;
import java.util.Collection;
import java.util.HashSet;
/**
* 概況 :壓縮文件<br>
*
* @version 1.00 (2011.12.02)
* @author SHNKCS 張軍 {@link <a target=_blank href="http://www.shanghaijiadun.com">上海加盾信息科技有限公司</a> <a target=_blank href="http://www.dlhighland.cn">張軍個人網站</a> <a target=_blank href="http://user.qzone.qq.com/360901061/">張軍QQ空間</a>}
*/
public class Compress implements Serializable {
private static final long serialVersionUID = 1L;
/** 源壓縮文件路徑,如果是目錄,以/杠結尾,不添加此目錄名,否則添加此目錄名/文件路徑 **/
public Collection<String> srcPaths = new HashSet<String>();
/** 目標壓縮文件路徑 **/
public String descPath;
/** 編碼 **/
public String encoding = "UTF-8";
/** 是否覆蓋 **/
public String overWrite;
/** 壓縮文件根目錄(多個目錄用/隔開) **/
public String destROOTName;
}壓縮文件屬性操作
package zj.compress.bean;
import java.io.Serializable;
/**
* 概況 :壓縮文件屬性操作<br>
*
* @version 1.00 (2011.12.02)
* @author SHNKCS 張軍 {@link <a target=_blank href="http://www.shanghaijiadun.com">上海加盾信息科技有限公司</a> <a target=_blank href="http://www.dlhighland.cn">張軍個人網站</a> <a target=_blank href="http://user.qzone.qq.com/360901061/">張軍QQ空間</a>}
*/
public class CompressAttr implements Serializable {
private static final long serialVersionUID = 1L;
/** 壓縮內文件路徑 **/
public String descPath;
/** 文件大小 **/
public long length;
/** 是否是目錄 **/
public boolean directory;
/** 文件名 **/
public String fileName;
}枚舉壓縮類型
/**
* @Description Encoding.java
* @author 張軍
* @date 2018年9月18日 下午9:24:07
* @version V1.0
*/
package zj.compress.bean;
/**
* @author 張軍
* @date 2018年9月18日 下午9:24:07
* @version V1.0
*/
/**
* 枚舉壓縮類型
*
* @author zhangjun
*
*/
public class Enums {
/**
* 壓縮文件擴展名
*
* @author zhangjun
*
*/
public static enum FileExtension {
ZIP("zip", "zip"), RAR("rar", "rar");
private final String value;
private final String name;
/**
* 獲取值
*
* @return 值
*/
public String getValue() {
return value;
}
/**
* 獲取名稱
*
* @return 名稱
*/
public String getName() {
return name;
}
/**
* 構造值-名稱
*
* @param value
* 值
* @param name
* 名稱
*/
FileExtension(String value, String name) {
this.value = value;
this.name = name;
}
}
/**
* ant下的zip工具默認壓縮編碼為UTF-8編碼, 而winRAR軟件壓縮是用的windows默認的GBK或者GB2312編碼 所以解壓縮時要制定編碼格式
*
* @author zhangjun
*
*/
public static enum Encoding {
/**
* ASCII
*/
ASCII("ASCII", "ASCII"),
/**
* MBCS
*/
MBCS("MBCS", "MBCS"),
/**
* GB2312
*/
GB2312("GB2312", "GB2312"),
/**
* GBK
*/
GBK("GBK", "GBK"),
/**
* UNICODE
*/
UNICODE("UNICODE", "UNICODE"),
/**
* UTF8
*/
UTF8("UTF-8", "UTF-8");
private final String value;
private final String name;
/**
* 獲取值
*
* @return 值
*/
public String getValue() {
return value;
}
/**
* 獲取名稱
*
* @return 名稱
*/
public String getName() {
return name;
}
/**
* 構造值-名稱
*
* @param value
* 值
* @param name
* 名稱
*/
Encoding(String value, String name) {
this.value = value;
this.name = name;
}
}
/**
* 是否覆蓋
*
* @author zhangjun
*
*/
public static enum OverWrite {
DEFAULT("", "重復時重命名"), OVER("1", "覆蓋"), NO_OVER("2", "不覆蓋");
private final String value;
private final String name;
/**
* 獲取值
*
* @return 值
*/
public String getValue() {
return value;
}
/**
* 獲取名稱
*
* @return 名稱
*/
public String getName() {
return name;
}
/**
* 構造值-名稱
*
* @param value
* 值
* @param name
* 名稱
*/
OverWrite(String value, String name) {
this.value = value;
this.name = name;
}
}
}解壓縮文件
package zj.compress.bean;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
* 概況 :解壓縮文件<br>
*
* @version 1.00 (2011.12.02)
* @author SHNKCS 張軍 {@link <a target=_blank href="http://www.shanghaijiadun.com">上海加盾信息科技有限公司</a> <a target=_blank href="http://www.dlhighland.cn">張軍個人網站</a> <a target=_blank href="http://user.qzone.qq.com/360901061/">張軍QQ空間</a>}
*/
public class UnCompress implements Serializable {
private static final long serialVersionUID = 1L;
/** 壓縮文件中的屬性對象集合 **/
public List<CompressAttr> compressAttrs = new ArrayList<CompressAttr>();
/** 壓縮文件路徑 **/
public String unrarPath;
/** 源壓縮文件路徑 **/
public String srcPath;
/** 解壓目標壓縮文件路徑 **/
public String descPath;
/** 編碼 **/
public String encoding = "UTF-8";
/** 是否覆蓋{@link zj.compress.bean.Enums.OverWrite} **/
public String overWrite;
}壓縮工具類
package zj.compress.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.Serializable;
import java.util.Collection;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream;
import zj.check.util.CheckUtil;
import zj.common.exception.ServiceException;
import zj.compress.bean.Compress;
import zj.io.util.FileUtil;
/**
* 壓縮工具類
* @version 1.00 (2011.12.02)
* @author SHNKCS 張軍 {@link <a target=_blank href="http://www.shanghaijiadun.com">上海加盾信息科技有限公司</a> <a target=_blank href="http://www.dlhighland.cn">張軍個人網站</a> <a target=_blank href="http://user.qzone.qq.com/360901061/">張軍QQ空間</a>}
*/
public class CompressUtil implements Serializable {
// private static Logger logger = Logger.getLogger(Compress.class);
private static final long serialVersionUID = 1L;
/**
* 壓縮文件夾/文件
*
* @param bean
* 壓縮對象
*/
public static void zip(Compress bean) {
ZipOutputStream out = null;
try {
Collection<String> srcPaths = bean.srcPaths;
String destPath = bean.descPath;
String destEncoding = bean.encoding;
if (srcPaths.size() == 0) {
throw new ServiceException("源文件夾/文件必須設置【zj.compress.bean.Compress.srcPaths】");
}
if (CheckUtil.isNull(destPath)) {
throw new ServiceException("目標文件【zj.compress.bean.Compress.destPath】");
}
String destRootName = bean.destROOTName;
if (CheckUtil.isNull(destRootName)) {
destRootName = "";
} else {
destRootName += "/";
}
// 壓縮目標文件
File destFile = new File(destPath);
// 創建文件目錄
FileUtil.createFolderOrFile(destFile);
// 創建壓縮文件流
out = new ZipOutputStream(destFile);
// 設置壓縮文件編碼
out.setEncoding(CheckUtil.isNull(destEncoding) ? "GBK" : destEncoding);
// 開始循環文件壓縮
for (String srcPath : srcPaths) {
srcPath = FileUtil.linuxSeparator(srcPath);
File fileOrDirectory = new File(srcPath);
if (fileOrDirectory.isDirectory()) {
// 如果是目錄
if (srcPath.endsWith("/")) {
// 不添加此目錄名
File[] entries = fileOrDirectory.listFiles();
for (int i = 0; i < entries.length; i++) {
// 遞歸壓縮,更新curPaths
zipFileOrDirectory(out, entries[i], destRootName, destPath, 0);
}
} else {
// 添加目錄名
zipFileOrDirectory(out, fileOrDirectory, destRootName, destPath, 0);
}
} else {
// 添加文件
zipFileOrDirectory(out, fileOrDirectory, destRootName, destPath, 0);
}
}
} catch (Exception e) {
throw new ServiceException(e);
} finally {
if (out != null) {
try {
out.close();
} catch (IOException ex) {
}
}
}
}
/**
* 遞歸壓縮文件或目錄
*
* @param out
* 壓縮輸出流對象
* @param fileOrDirectory
* 要壓縮的文件或目錄對象
* @param curPath
* 當前壓縮條目的路徑,用于指定條目名稱的前綴
* @throws IOException
*/
private static void zipFileOrDirectory(ZipOutputStream out, File fileOrDirectory, String curPath, String samePath, int byte_length) {
FileInputStream in = null;
try {
if (!fileOrDirectory.isDirectory()) {
// 壓縮文件
if (byte_length == 0)
byte_length = 1024;
byte[] buffer = new byte[byte_length];
in = new FileInputStream(fileOrDirectory);
boolean isExist = fileOrDirectory.getPath().equalsIgnoreCase(samePath);
if (!isExist) {
ZipEntry entry = new ZipEntry(curPath + fileOrDirectory.getName());
// 設置壓縮對象
out.putNextEntry(entry);
int bytes_read = -1;
while ((bytes_read = in.read(buffer)) != -1) {
out.write(buffer, 0, bytes_read);
}
}
out.closeEntry();
} else {
// 壓縮目錄
File[] entries = fileOrDirectory.listFiles();
for (int i = 0; i < entries.length; i++) {
// 遞歸壓縮,更新curPaths
zipFileOrDirectory(out, entries[i], curPath + fileOrDirectory.getName() + "/", samePath, byte_length);
}
}
} catch (Exception e) {
throw new ServiceException(e);
} finally {
if (in != null) {
try {
in.close();
} catch (IOException ex) {
}
}
}
}
}
本文為張軍原創文章,轉載無需和我聯系,但請注明來自張軍的軍軍小站,個人博客http://www.dlhighland.cn
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

