压缩、解压缩工具类
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.zhangjunbk.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://www.zhangjunbk.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://www.zhangjunbk.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://www.zhangjunbk.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://www.zhangjunbk.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://www.zhangjunbk.com