-Java压缩解压文件、文件夹的一个工具类

来源:互联网 发布:移动网络电视打不开 编辑:程序博客网 时间:2024/05/16 14:56

2010年做项目的时候偶尔要用到压缩解压目录相关操作,本来以为随便网上搜索一下就有,结果找了半天都没找到,无奈去看下apacheCompress的api,自己写了个。,使用了apache的Compress,common-io。

       有一个比较容易出错的地方,有些压缩方法,如果压缩目录中有空文件夹,可能是解压不出来的,

这是因为压缩的时候,只对于文件写了entryName,文件夹的entryName没有写。

这种情况下,zip文件的entry树结构:大概如下:

Java代码  收藏代码
  1. +目录A/目录B/目录C/文件1  
  2.   
  3. +目录A/目录B/目录D/文件2  

 

这种解压的时候如果CD层没有另外的目录,结果与正常的压缩方法没区别,层级目录能正常创建。

但是如果有一个E的空目录和在CD同级的情况,解压完不会有E目录

正常的压缩目录应该为

Java代码  收藏代码
  1. +目录A  
  2.   
  3. +目录A/目录B  
  4.   
  5. +目录A/目录B/目录C  
  6.   
  7. +目录A/目录B/目录D  
  8.   
  9. +目录A/目录B/目录E  
  10.   
  11. +目录A/目录B/目录C/文件1  
  12.   
  13. +目录A/目录B/目录D/文件2  

 

 

附代码:

Java代码  收藏代码
  1. public final class ZipTools {  
  2.   
  3.     private int bufferLen = 1024 * 1024;  
  4.   
  5.     /** 
  6.      * 私有化构造方法,prevents calls from subclass 
  7.      */  
  8.     private ZipTools() {  
  9.         throw new UnsupportedOperationException();  
  10.     }  
  11.   
  12.     private ZipTools(int bufferLen) {  
  13.         this.bufferLen = bufferLen;  
  14.     }  
  15.   
  16.     public static ZipTools getInstance() {  
  17.         return new ZipTools(1024 * 1024);  
  18.     }  
  19.   
  20.     public static ZipTools getInstance(int bufferLen) {  
  21.         return new ZipTools(bufferLen);  
  22.     }  
  23.   
  24.     /** 
  25.      * 用于单文件压缩 
  26.      */  
  27.     protected void doCompress(File srcFile, File destFile) throws IOException {  
  28.         ZipArchiveOutputStream out = null;  
  29.         InputStream is = null;  
  30.         try {  
  31.             is = new BufferedInputStream(new FileInputStream(srcFile), bufferLen);  
  32.             out = new ZipArchiveOutputStream(new BufferedOutputStream(new FileOutputStream(destFile), bufferLen));  
  33.             ZipArchiveEntry entry = new ZipArchiveEntry(srcFile.getName());  
  34.             entry.setSize(srcFile.length());  
  35.             out.putArchiveEntry(entry);  
  36.             IOUtils.copy(is, out);  
  37.             out.closeArchiveEntry();  
  38.         } finally {  
  39.             IOUtils.closeQuietly(is);  
  40.             IOUtils.closeQuietly(out);  
  41.         }  
  42.     }  
  43.   
  44.     /** 
  45.      * 解压文件 
  46.      * @param zipFile 
  47.      * @param outDir 
  48.      * @throws IOException 
  49.      * 90s 
  50.      */  
  51.     public void doDecompress(String zipFilePath, String outDirStr) throws IOException {  
  52.         File zipFile = new File(zipFilePath);  
  53.         File outDir = new File(outDirStr);  
  54.         ZipArchiveInputStream is = null;  
  55.         try {  
  56.             is = new ZipArchiveInputStream(new BufferedInputStream(new FileInputStream(zipFile), bufferLen));  
  57.             ZipArchiveEntry entry = null;  
  58.             while ((entry = is.getNextZipEntry()) != null) {  
  59.                 if (entry.isDirectory()) {  
  60.                     File directory = new File(outDir, entry.getName());  
  61.                     directory.mkdirs();  
  62.                 } else {  
  63.                     OutputStream os = null;  
  64.                     try {  
  65.                         os = new BufferedOutputStream(new FileOutputStream(new File(outDir, entry.getName())),  
  66.                                 bufferLen);  
  67.                         IOUtils.copy(is, os);  
  68.                     } finally {  
  69.                         IOUtils.closeQuietly(os);  
  70.                     }  
  71.                 }  
  72.             }  
  73.         } finally {  
  74.             IOUtils.closeQuietly(is);  
  75.         }  
  76.     }  
  77.   
  78.     /** 
  79.      *  解压指定zip文件到目录,使用新方法 
  80.      * @param outDir 输出到的目录,此目录如果不存在会自动创建 
  81.      * @param unZipfileName 需要解压的zip文件名 
  82.      * @throws IOException 
  83.      * 30s 
  84.      */  
  85.     public static void unZip(String outDirPath, String unZipfilePath) throws IOException {  
  86.         FileOutputStream fileOutStream = null;  
  87.         InputStream inputStream = null;  
  88.         ZipFile zipFile = null;  
  89.         File outDir = new File(outDirPath);  
  90.         File unZipfile = new File(unZipfilePath);  
  91.   
  92.         if (!unZipfile.exists()) {  
  93.             throw new FileNotFoundException("File to upzip:" + unZipfilePath + " not found!");  
  94.         }  
  95.         try {  
  96.             zipFile = new ZipFile(unZipfile);  
  97.             Enumeration<?> e = zipFile.getEntries();  
  98.             while (e.hasMoreElements()) {  
  99.                 ZipArchiveEntry entry = (ZipArchiveEntry) e.nextElement();  
  100.                 File file = new File(outDir, entry.getName());  
  101.                 //File file = getRealFileName(outDirPath, entry.getName());  
  102.                 if (entry.isDirectory()) {  
  103.                     file.mkdirs();  
  104.                 } else {  
  105.                     // 如果指定文件的目录不存在,则创建之.  
  106.                     File parent = file.getParentFile();  
  107.                     if (!parent.exists()) {  
  108.                         parent.mkdirs();  
  109.                     }  
  110.                     try {  
  111.                         inputStream = zipFile.getInputStream(entry);  
  112.                         fileOutStream = new FileOutputStream(file);  
  113.                         IOUtils.copy(inputStream, fileOutStream);  
  114.                     } finally {  
  115.                         IOUtils.closeQuietly(inputStream);  
  116.                         IOUtils.closeQuietly(fileOutStream);  
  117.                     }  
  118.                 }  
  119.             }  
  120.         } finally {  
  121.             ZipFile.closeQuietly(zipFile);  
  122.             IOUtils.closeQuietly(inputStream);  
  123.         }  
  124.   
  125.     }  
  126.   
  127.     /** 
  128.      * 从文件中解压一个指定文件 
  129.      * @param fileName 
  130.      * @param zipFile 
  131.      * @return 
  132.      * @throws IOException  
  133.      * @throws ZipException  
  134.      */  
  135.     public InputStream readFileFromSingleFile(ZipFile zipFile, ZipArchiveEntry entry) throws IOException {  
  136.         InputStream inputStream = zipFile.getInputStream(entry);  
  137.         return inputStream;  
  138.     }  
  139.   
  140.     /** 
  141.      * 把一个目录打包到一个指定的zip文件中 
  142.      * @param dirStr           目录绝对地址 
  143.      * @param pathName       zip文件内相对结构 
  144.      * @throws IOException  
  145.      */  
  146.     private void packFiles(ZipArchiveOutputStream out, File dir, String pathName) throws IOException {  
  147.         InputStream is = null;  
  148.         //返回此绝对路径下的文件  
  149.         File[] files = dir.listFiles();  
  150.         if (files == null || files.length < 1) {  
  151.             return;  
  152.         }  
  153.         for (int i = 0; i < files.length; i++) {  
  154.             File zFile = files[i];  
  155.             out.putArchiveEntry(new ZipArchiveEntry(zFile, pathName + zFile.getName()));  
  156.             //判断此文件是否是一个文件夹  
  157.             if (zFile.isDirectory()) {  
  158.                 packFiles(out, zFile, pathName + zFile.getName() + "/");  
  159.             } else {  
  160.                 try {  
  161.                     //out.putArchiveEntry(new ZipArchiveEntry(pathName + files[i].getName()));  
  162.                     is = new BufferedInputStream(new FileInputStream(zFile), bufferLen);  
  163.                     IOUtils.copy(is, out);  
  164.                 } finally {  
  165.                     is.close();  
  166.                 }  
  167.             }  
  168.         }  
  169.     }  
  170.   
  171.     /** 
  172.      * 压缩文件或者文件夹 
  173.      * @param srcFileStr 待压缩文件或文件夹路径 
  174.      * @param destFileStr 目标文件路径 
  175.      * @throws IOException 
  176.      */  
  177.     public void zip(String srcFileStr, String destFileStr) throws IOException {  
  178.         File destFile = new File(destFileStr);  
  179.         File srcFile = new File(srcFileStr);  
  180.         zip(srcFile, destFile);  
  181.     }  
  182.   
  183.     /** 
  184.      * 压缩文件 
  185.      * @param srcFile 待压缩文件或文件夹 
  186.      * @param destFile目标压缩文件 
  187.      * @throws IOException 
  188.      */  
  189.     public void zip(File srcFile, File destFile) throws IOException {  
  190.         ZipArchiveOutputStream out = null;  
  191.   
  192.         // 如果压缩文件存放目录不存在,则创建之.  
  193.         File pfile = destFile.getParentFile();  
  194.         if (!pfile.exists()) {  
  195.             pfile.mkdirs();  
  196.         }  
  197.         //如果是文件  
  198.         if (srcFile.isFile()) {  
  199.             doCompress(srcFile, destFile);  
  200.             return;  
  201.         } else {  
  202.             try {  
  203.                 out = new ZipArchiveOutputStream(new BufferedOutputStream(new FileOutputStream(destFile), bufferLen));  
  204.                 packFiles(out, srcFile, "");  
  205.                 out.closeArchiveEntry();  
  206.             } finally {  
  207.                 IOUtils.closeQuietly(out);  
  208.             }  
  209.         }  
  210.     }  
  211.   
  212.     /** 
  213.      * 将压缩文件中部分文件压缩到另外一个文件中 
  214.      */  
  215.     public void copyEntryToAnother(ZipFile srcFile, File destFile, ArrayList<ZipArchiveEntry> entryList)  
  216.             throws IOException {  
  217.         ZipArchiveOutputStream out = null;  
  218.         FileOutputStream fileOutStream = null;  
  219.         InputStream inputStream = null;  
  220.   
  221.         //建立临时目录  
  222.         String tempDirStr = System.getProperty("java.io.tmpdir") + "temp"  
  223.                 + File.separatorChar;  
  224.         File tempDir = new File(tempDirStr, String.valueOf(FlowNoGenerator.instance().getFlowNo()));  
  225.         tempDir.mkdirs();  
  226.   
  227.         try {  
  228.             //解压  
  229.             for (ZipArchiveEntry entry : entryList) {  
  230.                 File file = new File(tempDir, entry.getName());  
  231.                 if (entry.isDirectory()) {  
  232.                     file.mkdirs();  
  233.                 } else {  
  234.                     // 如果指定文件的目录不存在,则创建之.  
  235.                     File parent = file.getParentFile();  
  236.                     if (!parent.exists()) {  
  237.                         parent.mkdirs();  
  238.                     }  
  239.                     try {  
  240.                         inputStream = srcFile.getInputStream(entry);  
  241.                         fileOutStream = new FileOutputStream(file);  
  242.                         IOUtils.copy(inputStream, fileOutStream);  
  243.                     } finally {  
  244.                         IOUtils.closeQuietly(inputStream);  
  245.                         IOUtils.closeQuietly(fileOutStream);  
  246.                     }  
  247.                 }  
  248.             }  
  249.             //压缩  
  250.             zip(tempDir, destFile);  
  251.         } finally {  
  252.             FileUtils.deleteQuietly(tempDir);  
  253.         }  
  254.         IOUtils.closeQuietly(out);  
  255.     }  
  256.    
  257.   

0 0
原创粉丝点击