java压缩和解压问题

今天调用java.util.zip包进行压缩和解压,结果发现后台老是报错:

java.lang.IllegalArgumentException  

at   java.util.zip.ZipInputStream.getUTF8String(ZipInputStream.java:285)  

搞了半天,一直没理解,后来想想这方法的名称是getUTF8String,很可能就是中文名的文件让这个出错的。

上网一搜结果就出来了。

再试试有什么工具包可以解决这个问题,发现Apache Ant提供的zip工具org.apache.tools.zip实现zip压缩和解压功能。

参考代码如下:

import java.io.BufferedInputStream;   
import java.io.BufferedOutputStream;   
import java.io.File;   
import java.io.FileInputStream;   
import java.io.FileOutputStream;   
import java.io.IOException;   
import java.io.InputStream;   
import java.util.Enumeration;   
import java.util.jar.JarEntry;   
import java.util.jar.JarOutputStream;   
import java.util.jar.Manifest;   
  
import org.apache.log4j.Logger;   
import org.apache.tools.zip.ZipEntry;   
import org.apache.tools.zip.ZipFile;   
import org.apache.tools.zip.ZipOutputStream;   
  
/**  
 * 功能:zip压缩、解压(支持中文文件名)  
 * 说明:使用Apache Ant提供的zip工具org.apache.tools.zip实现zip压缩和解压功能.  
 * 解决了由于java.util.zip包不支持汉字的问题。  
 * 使用java.util.zip包时,当zip文件中有名字为中文的文件时,  
 * 就会出现异常:  
 * "Exception  in thread "main " java.lang.IllegalArgumentException  
 * at   java.util.zip.ZipInputStream.getUTF8String(ZipInputStream.java:285)  
 * <p/>  
 * <p/>  
 * 注意:  
 * 1、使用时把ant.jar放到classpath中,程序中使用 import org.apache.tools.zip.*;  
 * 2、本程序使用Ant 1.7.1 中的ant.jar部分类,ant-zip-1.7.1只保留Ant的zip压缩功能,以减小ant.jar的大小。  
 * 4、ZipEntry的isDirectory()方法中,目录以"/"结尾。  
 * <p/>  
 * <p/>  
 * ------------------------------------------------  
 * 可将主函数注释去掉以单独测试ZipFileUtils类。  
 * Compile:  
 * javac -cp Ant.jar ZipFileUtils.java  
 * <p/>  
 * Usage:(将ant.jar直接放在当前目录)  
 * 压缩: java -cp Ant.jar;.  ZipFileUtils -zip [directoryName | fileName]...  
 * 解压: java -cp Ant.jar;.  ZipFileUtils -unzip "fileName.zip"  
 * <p/>  
 * ------------------------------------------------  
 */  
public class ZipFileUtils   
{   
    private static Logger log = Logger.getLogger(ZipFileUtils.class);   
  
    private static int bufSize = 8096;    //size of bytes   
  
  
    /**  
     * 压缩文件夹内的所有文件和目录(不支持有中文目录或文件名)。  
     *  
     * @param zipDirectory 需要压缩的文件夹名  
     * @return 成功返回null,否则返回失败信息  
     */  
    public static String zip(String zipDirectory)   
    {   
        File zipDir = new File(zipDirectory);   
        return zip(zipDirectory, zipDir.getPath(), false);   
    }   
  
    /**  
     * 压缩文件夹内的所有文件和目录(不支持有中文目录或文件名)。  
     *  
     * @param zipDirectory   需要压缩的文件夹名  
     * @param zipFileName    压缩后的zip文件名,如果后缀不是".zip, .jar, .war", 自动添加后缀".zip"。  
     * @param includeSelfDir 是否包含自身文件夹  
     * @return 成功返回null,否则返回失败信息  
     */  
    public static String zip(String zipDirectory, String zipFileName, boolean includeSelfDir)   
    {   
        File zipDir = new File(zipDirectory);   
        File[] willZipFileArr;   
        if(includeSelfDir || zipDir.isFile())   
        {   
            willZipFileArr = new File[]{zipDir};   
        }   
        else  
        {   
            willZipFileArr = zipDir.listFiles();   
        }   
        return zip(willZipFileArr, zipFileName);   
    }   
  
    /**  
     * 压缩多个文件或目录。可以指定多个单独的文件或目录。  
     *  
     * @param files       要压缩的文件或目录组成的<code>File</code>数组。  
     * @param zipFileName 压缩后的zip文件名,如果后缀不是".zip, .jar, .war",自动添加后缀".zip"。  
     * @return 成功返回null,否则返回失败信息  
     */  
    public static String zip(File[] files, String zipFileName)   
    {   
        if(files == null)   
        {   
            return "待压缩的文件不存在。";   
        }   
  
        //未指定压缩文件名,默认为"ZipFile"   
        if(zipFileName == null || zipFileName.equals(""))   
            zipFileName = "ZipFile";   
  
        //添加".zip"后缀   
        if(!zipFileName.toLowerCase().endsWith(".zip")   
            && !zipFileName.toLowerCase().endsWith(".jar") && !zipFileName.toLowerCase().endsWith(".war"))   
            zipFileName += ".zip";   
  
        JarOutputStream jarOutput = null;   
        try  
        {   
            jarOutput = new JarOutputStream(new FileOutputStream(zipFileName), new Manifest());   
  
            for(File file : files)   
            {   
                zipFiles(file, jarOutput, "");   
            }   
            log.info("压缩文件成功:" + zipFileName);   
  
        } catch(Exception e)   
        {   
            log.error("异常", e);   
        } finally  
        {   
            if(jarOutput != null)   
            {   
                try  
                {   
                    jarOutput.close();   
                } catch(IOException e)   
                {   
                    log.error("jarOutput.close()异常", e);   
                }   
            }   
        }   
        return null;   
    }   
  
    /**  
     * @param file     压缩文件  
     * @param jos      JarOutputStream  
     * @param pathName 相对路径  
     * @throws Exception 异常  
     */  
    private static void zipFiles(File file, JarOutputStream jos, String pathName)   
        throws Exception   
    {   
        String fileName = pathName + file.getName();   
        if(file.isDirectory())   
        {   
            fileName = fileName + "/";   
            jos.putNextEntry(new JarEntry(fileName));   
            String fileNames[] = file.list();   
            if(fileNames != null)   
            {   
                for(int i = 0; i < fileNames.length; i++)   
                {   
                    zipFiles(new File(file, fileNames[i]), jos, fileName);   
                }   
                jos.closeEntry();   
            }   
        }   
        else  
        {   
            JarEntry jarEntry = new JarEntry(fileName);   
            BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));   
            jos.putNextEntry(jarEntry);   
  
            byte[] buf = new byte[bufSize];   
            int len;   
            while((len = in.read(buf)) >= 0)   
            {   
                jos.write(buf, 0, len);   
            }   
            in.close();   
            jos.closeEntry();   
        }   
    }   
  
    /**  
     * 压缩文件夹内的所有文件和目录。  
     *  
     * @param zipDirectory 需要压缩的文件夹名  
     * @return 成功返回null,否则返回失败信息  
     */  
    public static String antzip(String zipDirectory)   
    {   
        File zipDir = new File(zipDirectory);   
        return antzip(zipDirectory, zipDir.getPath(), false);   
    }   
  
    /**  
     * 压缩文件夹内的所有文件和目录。  
     *  
     * @param zipDirectory   需要压缩的文件夹名  
     * @param zipFileName    压缩后的zip文件名,如果后缀不是".zip, .jar, .war", 自动添加后缀".zip"。  
     * @param includeSelfDir 是否包含自身文件夹  
     * @return 成功返回null,否则返回失败信息  
     */  
    public static String antzip(String zipDirectory, String zipFileName, boolean includeSelfDir)   
    {   
        File zipDir = new File(zipDirectory);   
        File[] willZipFileArr;   
        if(includeSelfDir || zipDir.isFile())   
        {   
            willZipFileArr = new File[]{zipDir};   
        }   
        else  
        {   
            willZipFileArr = zipDir.listFiles();   
        }   
        return antzip(willZipFileArr, zipFileName);   
    }   
  
    /**  
     * 压缩多个文件或目录。可以指定多个单独的文件或目录。  
     *  
     * @param files       要压缩的文件或目录组成的<code>File</code>数组。  
     * @param zipFileName 压缩后的zip文件名,如果后缀不是".zip, .jar, .war",自动添加后缀".zip"。  
     * @return 成功返回null,否则返回失败信息  
     */  
    public static String antzip(File[] files, String zipFileName)   
    {   
        //未指定压缩文件名,默认为"ZipFile"   
        if(zipFileName == null || zipFileName.equals(""))   
            zipFileName = "ZipFile";   
  
        //添加".zip"后缀   
        if(!zipFileName.toLowerCase().endsWith(".zip")   
            && !zipFileName.toLowerCase().endsWith(".jar") && !zipFileName.toLowerCase().endsWith(".war"))   
            zipFileName += ".zip";   
  
        ZipOutputStream zipOutput = null;   
        try  
        {   
            zipOutput = new ZipOutputStream(   
                new BufferedOutputStream(new FileOutputStream(zipFileName)));   
            zipOutput.setEncoding("GBK");   
  
            for(File file : files)   
            {   
                antzipFiles(file, zipOutput, "");   
            }   
  
            log.info("压缩文件成功:" + zipFileName);   
        } catch(Exception e)   
        {   
            log.error("压缩文件异常", e);   
            return e.getMessage();   
        }   
        finally  
        {   
            try  
            {   
                assert zipOutput != null;   
                zipOutput.close();   
            } catch(Exception e)   
            {   
                log.error("异常", e);   
            }   
        }   
        return null;   
    }   
  
    /**  
     * @param file      压缩文件  
     * @param zipOutput ZipOutputStream  
     * @param pathName  相对路径  
     * @throws Exception 异常  
     */  
    private static void antzipFiles(File file, ZipOutputStream zipOutput, String pathName)   
        throws Exception   
    {   
        String fileName = pathName + file.getName();   
        if(file.isDirectory())   
        {   
            fileName = fileName + "/";   
            zipOutput.putNextEntry(new ZipEntry(fileName));   
            String fileNames[] = file.list();   
            if(fileNames != null)   
            {   
                for(int i = 0; i < fileNames.length; i++)   
                {   
                    antzipFiles(new File(file, fileNames[i]), zipOutput, fileName);   
                }   
                zipOutput.closeEntry();   
            }   
        }   
        else  
        {   
            ZipEntry jarEntry = new ZipEntry(fileName);   
            BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));   
            zipOutput.putNextEntry(jarEntry);   
  
            byte[] buf = new byte[bufSize];   
            int len;   
            while((len = in.read(buf)) >= 0)   
            {   
                zipOutput.write(buf, 0, len);   
            }   
            in.close();   
            zipOutput.closeEntry();   
        }   
    }   
  
    /**  
     * 解压指定zip文件。  
     *  
     * @param unZipFile 需要解压的zip文件对象  
     * @return 成功返回null,否则返回失败信息  
     */  
    public static String unZip(File unZipFile)   
    {   
        return unZip(unZipFile.getPath(), null);   
    }   
  
    /**  
     * 解压指定zip文件到指定的目录。  
     *  
     * @param unZipFile    需要解压的zip文件对象  
     * @param destFileName 解压目的目录  
     * @return 成功返回null,否则返回失败信息  
     */  
    public static String unZip(File unZipFile, String destFileName)   
    {   
        return unZip(unZipFile.getPath(), destFileName);   
    }   
  
    /**  
     * 解压指定zip文件。  
     *  
     * @param unZipFileName 需要解压的zip文件名  
     * @return 成功返回null,否则返回失败信息  
     */  
    public static String unZip(String unZipFileName)   
    {   
        return unZip(unZipFileName, null);   
    }   
  
    /**  
     * 解压指定zip文件到指定的目录。  
     *  
     * @param unZipFileName 需要解压的zip文件名  
     * @param destFileName  解压目的目录,如果为null则为当前zip文件所有目录  
     * @return 成功返回null,否则返回失败信息  
     */  
    public static String unZip(String unZipFileName, String destFileName)   
    {   
        File unzipFile = new File(unZipFileName);   
  
        if(destFileName == null || destFileName.trim().length() == 0)   
        {   
            destFileName = unzipFile.getParent();   
        }   
  
        File destFile;   
        ZipFile zipFile = null;   
        try  
        {   
            zipFile = new ZipFile(unzipFile, "GBK");   
            for(Enumeration entries = zipFile.getEntries(); entries.hasMoreElements();)   
            {   
                ZipEntry entry = (ZipEntry) entries.nextElement();   
                destFile = new File(destFileName, entry.getName());   
  
                unZipFile(destFile, zipFile, entry); //执行解压   
            }   
        } catch(Exception e)   
        {   
            log.error("解压ZIP文件异常", e);   
            return e.getMessage();   
        }   
        finally  
        {   
            try  
            {   
                assert zipFile != null;   
                zipFile.close();   
            } catch(Exception e)   
            {   
                log.error("异常", e);   
            }   
        }   
        return null;   
    }   
  
    /* 执行解压 */  
    private static void unZipFile(File destFile, ZipFile zipFile, ZipEntry entry)   
        throws IOException   
    {   
        InputStream inputStream;   
        FileOutputStream fileOut;   
        if(entry.isDirectory()) //是目录,则创建之   
        {   
            destFile.mkdirs();   
        }   
        else //是文件   
        {   
            //如果指定文件的父目录不存在,则创建之.   
            File parent = destFile.getParentFile();   
            if(parent != null && !parent.exists())   
            {   
                parent.mkdirs();   
            }   
  
            inputStream = zipFile.getInputStream(entry);   
  
            fileOut = new FileOutputStream(destFile);   
            byte[] buf = new byte[bufSize];   
            int readedBytes;   
            while((readedBytes = inputStream.read(buf)) > 0)   
            {   
                fileOut.write(buf, 0, readedBytes);   
            }   
            fileOut.close();   
  
            inputStream.close();   
        }   
    }   
  
    /**  
     * 设置压缩或解压时缓冲区大小,单位字节。  
     *  
     * @param bufSize 缓冲区大小  
     */  
    public void setBufSize(int bufSize)   
    {   
        ZipFileUtils.bufSize = bufSize;   
    }   
  
    //主函数,用于测试ZipFileUtils类   
    public static void main(String[] args) throws Exception   
    {   
        //ZipFileUtils zip = new ZipFileUtils();   
        if(args.length >= 2)   
        {   
  
            if(args[0].equals("-zip"))   
            {   
                //将后续参数全部转化为File对象   
                File[] files = new File[args.length - 1];   
                for(int i = 0; i < args.length - 1; i++)   
                {   
                    files[i] = new File(args[i + 1]);   
                }   
  
                //将第一个文件名作为zip文件名   
                ZipFileUtils.antzip(files, files[0].getName());   
                return;   
            }   
            else if(args[0].equals("-unzip"))   
            {   
                ZipFileUtils.unZip(args[1]);   
                return;   
            }   
        }   
  
        String tmpFile = "D:/MyDocuments/Doc2009/2009-04/test/tagTable中文测试.zip";   
        ZipFileUtils.unZip(tmpFile);   
        ZipFileUtils.unZip(tmpFile, tmpFile.substring(0, tmpFile.lastIndexOf(".")));   
  
        String tmpDir = "D:\\SVN\\USCE.USEE\\PCT\\trunk\\src\\PCT_CJ001_Application\\src\\main\\webapp\\portals\\king0.1\\webapp";   
        //ZipFileUtils.antzip(tmpDir, tmpDir + "/../war/pctant.war", false);   
        ZipFileUtils.zip(tmpDir + "/test");   
        //ZipFileUtils.zip(tmpDir, tmpDir + "/../war/pct.war", false);   
  
        // -----------------   
        System.out.println("Usage:");   
        System.out.println("压缩:java ZipFileUtils -zip [directoryName | fileName]... ");   
        System.out.println("解压:java ZipFileUtils -unzip fileName.zip");   
        System.out.println();   
    }   
  
}  


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值