壓縮、解壓縮工具類
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://m.eyofj.com">張軍個人網站</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://m.eyofj.com">張軍個人網站</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://m.eyofj.com">張軍個人網站</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://m.eyofj.com">張軍個人網站</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://m.eyofj.com">張軍個人網站</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://m.eyofj.com
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
