java对 zip文件的压缩和解压(ant解决中文乱码)

Posted 倾舞绕梦

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java对 zip文件的压缩和解压(ant解决中文乱码)相关的知识,希望对你有一定的参考价值。

说明:

1、对于压缩的文件,当文件名称是中文时,若使用JDK API中自带的类(java.util.zip.ZipEntry; java.util.zip.ZipOutputStream;)进行压缩,压缩完成后,可以看到压缩包中的文件名称是乱码(文件的内容无乱码),所以使用ANT中的ant.jar中的类(org.apache.tools.zip.ZipEntry; org.apache.tools.zip.ZipOutputStream;)用来解决此问题;

2、解压缩时,如果压缩包中为空,则创建空文件夹

import 如下:

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 org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;
import org.apache.tools.zip.ZipOutputStream;

 

一、压缩文件(ZIP):

/**
     *@name    获取File对象
     *@description 相关说明
     *@param path 文件路径
     *@return File 
     *@throws IOException
     *@author   LJCH
     *@history 修订历史(历次修订内容、修订人、修订时间等)
     */
    public static File getFile(String path) throws IOException {
        // 创建文件对象
        File file = null;
        if (path != null && !path.equals("")) {
            file = new File(path);
        }
        if (!file.exists()) {
            file.createNewFile();
        }
        // 返回文件
        return file;
    }
    /**
     *@name    压缩文件
     *@description 相关说明
     *@param srcFilePath 源文件
     *@param destZipFile 目标文件
     *@return file 压缩文件的FILE对象
     *@throws IOException
     *@author   LJCH
     *@history 修订历史(历次修订内容、修订人、修订时间等)
     */
    public static File getZipFile(String srcFilePath, String destZipFile) throws IOException {
        return  getZipFile(new File(srcFilePath),destZipFile);
    }
    /**
     *@name    获取压缩文件的File
     *@description 相关说明
     *@param srcFile 源文件
     *@param destZipFile 目标文件
     *@return file 压缩文件的FILE对象
     *@throws IOException
     *@author   LJCH
     *@history 修订历史(历次修订内容、修订人、修订时间等)
     */
    public static File getZipFile(File srcFile, String destZipFile) throws IOException {
        final File zipFile = getFile(destZipFile);
        // 文件输出流
        final FileOutputStream outputStream =new FileOutputStream(zipFile);
        // 压缩流
        final ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream);
        if (srcFile.isDirectory()) {
            directory(zipOutputStream, srcFile);
        } else {
            zipFile(srcFile, zipOutputStream);
        }
        // 关闭压缩流、文件流
        zipOutputStream.close();
        outputStream.close();
        return zipFile;
    }
    /**
     *@name    递归压缩目录结构
     *@description 相关说明
     *@param zipOutputStream 压缩文件流
     *@param file file
     *@throws IOException
     *@author   LJCH
     *@history 修订历史(历次修订内容、修订人、修订时间等)
     */
    public static void directory(ZipOutputStream zipOutputStream, File file) throws IOException {
        final File[] files = file.listFiles();
        for (File fileTemp : files) {
            if (fileTemp.isDirectory()) {
                directory(zipOutputStream, fileTemp);
            } else {
                zipFile(fileTemp, zipOutputStream);
            }
        }

        if (files.length == 0) {
            try {
                zipOutputStream.putNextEntry(new ZipEntry(getPath(file) + File.separator));
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }
    /**
     *@name    获得该文件在压缩包中的相对路径
     *@description 相关说明
     *@param file  File
     *@return String
     *@author   LJCH
     *@history 修订历史(历次修订内容、修订人、修订时间等)
     */
    public static String getPath(File file) {
        final String str1 = file.getAbsolutePath();
        final int n1 = str1.length();
        final String str2 = file.getAbsolutePath();
        final int n2 = str2.length();
        final String str3 = file.getName();
        final int n3 = str3.length();
        final String str = str2.substring(n1 - n3, n2);
        return str;
    }
    /**
     * 将文件数据写入文件压缩流
     * @param file 带压缩文件
     * @param zipOutputStream 压缩文件流
     * @throws IOException
     */
    private static void zipFile(File file, ZipOutputStream zipOutputStream) throws IOException {
        if (file.exists()) {
            if (file.isFile()) {
                final FileInputStream fis = new FileInputStream(file);
                final BufferedInputStream bis = new BufferedInputStream(fis);
                final ZipEntry entry = new ZipEntry(file.getName());
                zipOutputStream.putNextEntry(entry);

                final int MAX_BYTE = 10 * 1024 * 1024; // 最大流为10MB
                long streamTotal = 0; // 接收流的容量
                int streamNum = 0; // 需要分开的流数目
                int leaveByte = 0; // 文件剩下的字符数
                byte[] buffer; // byte数据接受文件的数据

                streamTotal = bis.available(); // 获取流的最大字符数
                streamNum = (int) Math.floor(streamTotal / MAX_BYTE);
                leaveByte = (int) (streamTotal % MAX_BYTE);

                if (streamNum > 0) {
                    for (int i = 0; i < streamNum; i++) {
                        buffer = new byte[MAX_BYTE];
                        bis.read(buffer, 0, MAX_BYTE);
                        zipOutputStream.write(buffer, 0, MAX_BYTE);
                    }
                }

                // 写入剩下的流数据
                buffer = new byte[leaveByte];
                bis.read(buffer, 0, leaveByte); // 读入流
                zipOutputStream.write(buffer, 0, leaveByte); // 写入流
                zipOutputStream.closeEntry(); // 关闭当前的zip entry

                // 关闭输入流
                bis.close();
                fis.close();
            }
        }
    }

二、解压缩文件(ZIP)

/**
     *@name    解压zip格式压缩包
     *@description 相关说明
     *@param sourceZip 源文件
     *@param destDir 目标文件地址
     *@throws Exception
     *@author   LJCH
     *@history 修订历史(历次修订内容、修订人、修订时间等)
     */
    @SuppressWarnings("unchecked")
    private static void unzip(String sourceZip, String destDir) throws Exception {
        ZipFile zipFile = null;
        try {
            final File f = new File(sourceZip);
            if ((!f.exists()) && (f.length() <= 0)) {
                throw new RuntimeException("要解压的文件不存在!");
            }
            //一定要加上编码,之前解压另外一个文件,没有加上编码导致不能解压
            zipFile = new ZipFile(f, "gbk");
            String gbkPath;
            String strtemp;
            final Enumeration<ZipEntry> e = zipFile.getEntries();
            if (!e.hasMoreElements()) {
                final File dir = new File(destDir + File.separator + f.getName().substring(0, f.getName().lastIndexOf(".")));
                if (!dir.exists()) {
                    dir.mkdirs();
                }
                return;
            }
            while (e.hasMoreElements()) {
                final org.apache.tools.zip.ZipEntry zipEnt = e.nextElement();
                gbkPath = zipEnt.getName();
                strtemp = destDir + File.separator + gbkPath;
                if (zipEnt.isDirectory()) { //目录
                    final File dir = new File(strtemp);
                    if (!dir.exists()) {
                        dir.mkdirs();
                    }
                    continue;
                } else if (zipEnt.getName().substring(zipEnt.getName().length() - 1, zipEnt.getName().length()).equals(File.separator)) {
                    final File dir = new File(strtemp);
                    if (!dir.exists()) {
                        dir.mkdirs();
                    }
                    continue;
                } else {
                    // 读写文件
                    final InputStream is = zipFile.getInputStream(zipEnt);
                    final BufferedInputStream bis = new BufferedInputStream(is);
                    // 建目录
                    final String strsubdir = gbkPath;
                    for (int i = 0; i < strsubdir.length(); i++) {
                        if (strsubdir.substring(i, i + 1).equalsIgnoreCase("/")) {
                            final String temp = destDir + File.separator + strsubdir.substring(0, i);
                            final File subdir = new File(temp);
                            if (!subdir.exists()) {
                                subdir.mkdir();
                            }
                        }
                    }
                    final FileOutputStream fos = new FileOutputStream(strtemp);
                    final BufferedOutputStream bos = new BufferedOutputStream(fos);
                    int len;
                    final byte[] buff = new byte[1024];
                    while ((len = bis.read(buff)) != -1) {
                        bos.write(buff, 0, len);
                    }
                    bos.close();
                    fos.close();
                }
            }
        } catch (Exception e) {
            //logger.error("解压文件出现异常:", e);
            throw e;
        }finally{
            zipFile.close();
        }
    }

    /**
     *@name    解压文件用于后期扩展RAR等其他压缩格式
     *@description 相关说明
     *@param sourceFile 源文件
     *@param destDir  目标路径
     *@throws Exception
     *@author   LJCH
     *@history 修订历史(历次修订内容、修订人、修订时间等)
     */
    private static void unfile(String sourceFile, String destDir) throws Exception {
        // 根据类型,进行相应的解压缩
        final String type = sourceFile.substring(sourceFile.lastIndexOf(".") + 1);
        final File dir = new File(destDir);
        if(!dir.exists()){
            dir.mkdirs();
        }
        if (type.toLowerCase().equals("zip")) {
            unzip(sourceFile, destDir);
        } else {
            throw new RuntimeException("只支持zip格式的压缩包!"+type);
        }
    }
 
    /**
     *@name    解压到指定目录
     *@description 相关说明
     *@param sourceFile 源文件
     *@param destDir 目标目录
     *@throws Exception
     *@author   LJCH
     *@history 修订历史(历次修订内容、修订人、修订时间等)
     */
    public static void deCompress(String sourceFile, String destDir) throws Exception {
        if (sourceFile == null || destDir == null) {
            throw new RuntimeException("目录不能为空");
        }
        // 保证文件夹路径最后是"/"或者""
        final char lastChar = destDir.charAt(destDir.length() - 1);
        if (lastChar != ‘/‘ && lastChar != ‘\‘) {
            unfile(sourceFile, destDir+File.separator);
        }else{
            unfile(sourceFile, destDir);
        }
        
    }

    /**
     *@name    解压到指定目录
     *@description 相关说明
     *@param sourceFile 源文件
     *@param destDir 目标路径
     *@throws Exception
     *@author   LJCH
     *@history 修订历史(历次修订内容、修订人、修订时间等)
     */
    public static void deCompress(File sourceFile, String destDir) throws Exception {
        if (!sourceFile.exists() || sourceFile.isDirectory()) {
            throw new RuntimeException("文件不存在");
        }
        deCompress(sourceFile.getPath(), destDir);
    }
 
    /**
     *@name    解压到当前目录
     *@description 相关说明
     *@param sourceFile 源文件
     *@throws Exception
     *@author   LJCH
     *@history 修订历史(历次修订内容、修订人、修订时间等)
     */
    public static void deCompress(String sourceFile) throws Exception {
 
        // 获得文件目录
        int i = sourceFile.lastIndexOf("/");
        final int d = sourceFile.lastIndexOf("\");
        if (i == -1 && d == -1) {
            throw new RuntimeException("目录separator异常");
        } else if (i == -1) {
            i = d;
        }
        final String destDir = sourceFile.substring(0, i + 1);
        unfile(sourceFile, destDir);
    }
 
    /**
     *@name    解压到当前目录
     *@description 相关说明
     *@param sourceFile 源文件
     *@throws Exception
     *@author   LJCH
     *@history 修订历史(历次修订内容、修订人、修订时间等)
     */
    public static void deCompress(File sourceFile) throws Exception {
        if (!sourceFile.exists() || sourceFile.isDirectory()) {
            throw new RuntimeException("文件不存在");
        }
        deCompress(sourceFile.getPath());
    }

 

文中如有存在描述不正确,欢迎指正、补充!!!

以上是关于java对 zip文件的压缩和解压(ant解决中文乱码)的主要内容,如果未能解决你的问题,请参考以下文章

AntZipUtils基于Ant的Zip压缩解压缩工具类

Java能否对压缩文件进行操作,例如:对zip,rar,tar等文件进行复制。

java压缩中文zip,系统winrar解压改中文zip会出现乱码

Java中往zip压缩包追加文件

spring-ant-处理zip

请大神帮忙解决一个用java解压缩一个zip压缩格式字节流中文内容乱码问题!