所有工具類
最近碰到個需要下載zip壓縮/解壓縮包的需求,于是我在網上找了下別人寫好的zip工具類。但找了好多篇博客,總是發(fā)現有bug。因此就自己來寫了個工具類。
這個工具類的主要功能為:
(1)可以壓縮/解壓縮文件,也可以壓縮/解壓縮文件夾
(2)同時支持壓縮多級文件夾,工具內部做了遞歸處理
(3)碰到空的文件夾,也可以壓縮/解壓縮
(4)可以選擇是否保留原來的目錄結構,如果不保留,所有文件跑壓縮/解壓縮包根目錄去了,且空文件夾直接舍棄。注意:如果不保留文件原來目錄結構,在碰到文件名相同的文件時,會壓縮失敗。
(5)代碼中提供了壓縮和解壓縮文件的方法,可根據實際需求選擇方法。
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://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); // 創(chuàng)建文件目錄 FileUtil.createFolderOrFile(destFile); // 創(chuàng)建壓縮文件流 out = new ZipOutputStream(destFile); // 設置壓縮文件編碼 out.setEncoding(CheckUtil.isNull(destEncoding) ? "GBK" : destEncoding); // 開始循環(huán)文件壓縮 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) { } } } } }
zj.compress.bean.Compress
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://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; }
zj.compress.bean.CompressAttr
package zj.compress.bean; import java.io.Serializable; /** * 概況 :壓縮文件屬性操作<br> * * @version 1.00 (2011.12.02) * @author SHNKCS 張軍 {@link <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; }
zj.compress.bean.Enums
/** * @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; } } }
本文為張軍原創(chuàng)文章,轉載無需和我聯系,但請注明來自張軍的軍軍小站,個人博客http://m.eyofj.com
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

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