利用ant.jar进行解压缩

本文介绍了一种处理ZIP文件的方法,包括递归解压、文件修改及重新打包。通过遍历ZIP文件内的所有条目并针对不同类型的文件采取相应操作,实现了对特定文件的定位与修改。

package com.zoucq;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;

import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;
import org.apache.tools.zip.ZipOutputStream;
/**
 * 功能介绍:
 * 给定一个压缩包,从中找出目标文件,并进行修改
 * 要求是要遍历压缩包中所有的文件,当然就要递归解压缩子文件压缩包
 * 修改完文件之后,要把文件重新打包
 */
public class ZIP {
 
 public static void main(String args[]){
  ZIP zip = new ZIP();
  try {
   zip.release(new File("d:/zip.zip"));
  } catch (IOException e) {
   e.printStackTrace();
  }
 }


 /**
  * 循环递归解压缩
  * @param file  带解压缩的文件
  * @throws IOException
  * @throws DocumentException
  */
 @SuppressWarnings("unchecked")
 public  void release(File file) throws IOException{
  //只解析后缀为.rar的包
        if(file.getName().endsWith(".zip")){
      ZipFile zipFile = new ZipFile(file);
      //得到所有的ZipEntry,进行遍历
            Enumeration zEnumeration=zipFile.getEntries();
            ZipEntry zipEntry=null;
            while(zEnumeration.hasMoreElements()){
              zipEntry=(ZipEntry)zEnumeration.nextElement();
              if(zipEntry.isDirectory()){
               //如果是压缩包的子文件是文件夹,代码生成应该的文件夹
               unZipDir(file,zipEntry.getName());
              }else{
                 //如果子文件是压缩包就进行解压缩
               release(file, zipEntry, zipFile);
              }
            }
            zipFile.close();
            //遍历解压后的文件夹,继续解压,递归
            String zipFullName = file.getPath();
            String zipName = zipFullName.substring(0,zipFullName.lastIndexOf("."));
            File zipDirFile = new File(zipName);
            File[] subFile = zipDirFile.listFiles();
            for(int i = 0; i < subFile.length; i++){
             release(subFile[i]);
            }
            //删除旧的压缩文件
            file.delete(); 
            //重新压缩文件
            zipDir(zipDirFile,file);
            //删除解压后的文件夹
            deleteFile(zipDirFile);
        }else if(file.isDirectory()){
         File[] subFile = file.listFiles();
         for(int i = 0; i < subFile.length; i++){
          release(subFile[i]);
         }
        }else{
         if(file.getName().equalsIgnoreCase("XmlStructure.xml")){
          //TODO:找到目标文件进行修改
         }
        }
 }
 
 /**
  *
  * @param file
  * @param zipEntry
  * @param zipFile
  * @throws IOException
  */
 public void release(File file,ZipEntry zipEntry,ZipFile zipFile) throws IOException{
     byte[] buf=new byte[1024];
        OutputStream os=new BufferedOutputStream(new FileOutputStream(getRealFile(file.getPath(), zipEntry.getName())));
        InputStream is=new BufferedInputStream(zipFile.getInputStream(zipEntry));
        int readLen=0;
        while ((readLen=is.read(buf, 0, 1024))!=-1) {
         os.write(buf, 0, readLen);
        }
        is.close();
        os.close();
 }
 
 /**
  * 如果要解压缩的单元是一个文件夹
  * @param unZipFile
  * @param subDir
  */
 public void unZipDir(File unZipFile,String subDir){
  String dir = subDir.substring(0,subDir.lastIndexOf("/"));
  String unZipFileName = unZipFile.getPath();
  unZipFileName = unZipFileName.substring(0, unZipFileName.lastIndexOf("."));
  File file = new File(unZipFileName, dir);
  if(!file.exists()){
   file.mkdirs();
  }
 }
 
 /**
  * 如果获取的文件名是parentfile/file.txt,就需要先创建文件夹parentfile,然后解压缩出文件file.txt
  * @param baseDir 别解压缩的文件全路径  d:/file/unzipfile.epa
  * @param absFileName 可能是一个文件名 filename,也可能是一个带父文件夹的文件名 subfile/subzip
  * @return
  */
    public File getRealFile(String baseDir, String fileName) {
        String[] dirs = fileName.split("/");
        //
        File ret = new File(baseDir.substring(0,baseDir.lastIndexOf(".")));
        if (dirs.length > 1) {
         for (int i = 0; i < dirs.length - 1; i++) {
          ret = new File(ret, dirs[i]);
         }
        }
        if (!ret.exists()) {
         ret.mkdirs();
        }
        return new File(ret, dirs[dirs.length - 1]);
    }
   
    /**
     * 压缩文件夹
     * @param sourceFile   被压缩的文件夹
     * @param zipFile  压缩后的文件,默认与被压缩文件同路径
     * @throws IOException
     */
    public void zipDir(File sourceFile, File zipFile) throws IOException {  
        try {  
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(zipFile));  
            ZipOutputStream zos = new ZipOutputStream(bos);  
            zipFile(zos,sourceFile,"");
            zos.close();
        } catch (FileNotFoundException e) {  
           throw e;
        } catch (IOException e) {
         throw e;
  }  
    }  
   
    /**
     *
     * @param out  压缩文件的输出流
     * @param f  被压缩的文件
     * @param base 
     * @throws IOException
     * @throws Exception
     */
    public void zipFile(ZipOutputStream out, File f, String base) throws IOException{
        if (f.isDirectory()) {
           File[] fl = f.listFiles();
           //直接压缩一个空文件夹
           if(fl.length == 0 && base.length() == 0){
            //加一个反斜线 "/",表示新增的压缩节点是一个文件夹
            out.putNextEntry(new ZipEntry(f.getName() + "/"));
           }else{
            //增加一个压缩节点
               out.putNextEntry(new ZipEntry(base + "/"));
               base = base.length() == 0 ? "" : base + "/";
               for (int i = 0; i < fl.length; i++) {
                zipFile(out, fl[i], base + fl[i].getName());
               }           
           }
        }else {
           //如果直接压缩一个文件的时候,需要用到下面的一个判断。比如待压缩的文件为->d:/zip/2ewq3.txt
           base = base.length() == 0?f.getName():base;
           //增加一个压缩节点
           out.putNextEntry(new ZipEntry(base));
           BufferedInputStream bin = new BufferedInputStream(new FileInputStream(f));
           byte[] byteArray = new byte[1024];
           int len = 0;
           while ( (len = bin.read(byteArray)) != -1) {
            out.write(byteArray,0,len);
           }
           bin.close();
       }
    }
 
 /**
  * 删除文件或者文件夹
  * @param dirFile
  */
 public void deleteFile(File dirFile){
  if(dirFile.isDirectory()){
   File[] subFileList = dirFile.listFiles();
   for(int i = 0; i < subFileList.length; i++){
    deleteFile(subFileList[i]);
   }
   dirFile.delete();
  }else{
   dirFile.delete();
  }
 }
}

[CLASS] org.apache.tools.ant.Main org.apache.tools.ant.Task org.apache.tools.bzip2.CRC org.apache.tools.ant.Target org.apache.tools.ant.Project org.apache.tools.zip.ZipFile org.apache.tools.zip.ZipLong org.apache.tools.ant.Executor org.apache.tools.ant.Location org.apache.tools.tar.TarEntry org.apache.tools.tar.TarUtils org.apache.tools.zip.UnixStat org.apache.tools.zip.ZipEntry org.apache.tools.zip.ZipShort org.apache.tools.ant.XmlLogger org.apache.tools.tar.TarBuffer org.apache.tools.zip.JarMarker org.apache.tools.zip.ZipFile$1 org.apache.tools.ant.BuildEvent org.apache.tools.ant.MagicNames org.apache.tools.ant.types.Path org.apache.tools.ant.BuildLogger org.apache.tools.ant.Diagnostics org.apache.tools.ant.FileScanner org.apache.tools.ant.TaskAdapter org.apache.tools.ant.TypeAdapter org.apache.tools.ant.XmlLogger$1 org.apache.tools.mail.MailMessage org.apache.tools.tar.TarConstants org.apache.tools.ant.taskdefs.Ant org.apache.tools.ant.taskdefs.Apt org.apache.tools.ant.taskdefs.Cvs org.apache.tools.ant.taskdefs.Ear org.apache.tools.ant.taskdefs.Get org.apache.tools.ant.taskdefs.Jar org.apache.tools.ant.taskdefs.Tar org.apache.tools.ant.taskdefs.War org.apache.tools.ant.taskdefs.Zip org.apache.tools.ant.types.DirSet org.apache.tools.ant.types.Mapper org.apache.tools.ant.BuildListener org.apache.tools.ant.DefaultLogger org.apache.tools.ant.Diagnostics$1 org.apache.tools.ant.ExitException org.apache.tools.ant.PathTokenizer org.apache.tools.ant.ProjectHelper org.apache.tools.ant.TaskContainer org.apache.tools.zip.AsiExtraField org.apache.tools.zip.ZipExtraField org.apache.tools.ant.taskdefs.Copy org.apache.tools.ant.taskdefs.Echo org.apache.tools.ant.taskdefs.Exec org.apache.tools.ant.taskdefs.Exit org.apache.tools.ant.taskdefs.GZip org.apache.tools.ant.taskdefs.Java org.apache.tools.ant.taskdefs.Move org.apache.tools.ant.taskdefs.Nice org.apache.tools.ant.taskdefs.Pack org.apache.tools.ant.taskdefs.Rmic org
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值