当前位置: 首页 > news >正文

使用Java对文件进行解压缩

最近在一个项目中需要对文件进行自动的解压缩,Java提供了这种支持,还是挺好用的。

工具包封装在java.util.zip中。

 

1.首先是多个文件压缩成一个ZIP文件

思路:用一个ZipOutputStream包装一个目的ZIP文件--->遍历文件数组:对每一个文件创建一个ZipEntry并put进ZipOutputStream中。读取当前文件的数据流写入ZipOutputStream中。

代码实现:

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.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 *多文件压缩
 *@author wxisme
 *@time 2015-9-24 下午5:13:32
 */

public final class FilesToZip {
    
    private FilesToZip(){}
    
    /**
     * 压缩多个文件到一个zip文件中
     * @param files 待压缩文件数组
     * @param zipFilePath 压缩后的zip文件路径
     * @param fileName zip文件的名字
     * @return 是否成功
     */
    public static boolean fileToZip(File[] files,String zipFilePath,String fileName){
        boolean flag = false;
        FileInputStream fis = null;
        BufferedInputStream bis = null;
        FileOutputStream fos = null;
        ZipOutputStream zos = null;
        
        try {
            File zipFile = new File(zipFilePath + "/" + fileName +".zip");
            if(zipFile.exists()) {
                zipFile.delete();
            }
            File[] sourceFiles = files;
            fos = new FileOutputStream(zipFile);
            zos = new ZipOutputStream(new BufferedOutputStream(fos));
            byte[] bufs = new byte[1024*10];
            for(int i=0;i<sourceFiles.length;i++){
                //创建ZIP实体,并添加进压缩包
                ZipEntry zipEntry = new ZipEntry(sourceFiles[i].getName());
                zos.putNextEntry(zipEntry);
                //读取待压缩的文件并写进压缩包里
                fis = new FileInputStream(sourceFiles[i]);
                bis = new BufferedInputStream(fis, 1024*10);
                int read = 0;
                while((read=bis.read(bufs, 0, 1024*10)) != -1){
                    zos.write(bufs,0,read);
                }
            }
            flag = true;        
                
            
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        } finally{
            //关闭流
            try {
                if(null != bis) bis.close();
                if(null != zos) zos.close();
            } catch (IOException e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            }
        }
        
        return flag;
    }

}

2.对包含有文件夹的文件数组进行压缩

思路:遍历文件数组,判断是否是文件。如果是文件步骤同1,如果是文件夹(目录)则递归压缩这个文件夹。其他步骤和1类似。

代码实现:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 *多文件夹压缩
 *@author wxisme
 *@time 2015-9-24 下午7:36:06
 */
public final class MultiZip {
    
    public static void ZipFiles(ZipOutputStream out,String path,File... srcFiles) {  
        path = path.replaceAll("\\*", "/");  
        if(!path.endsWith("/")){  
            path+="/";
        }
        byte[] buf = new byte[1024];
        try {  
            for(int i=0;i<srcFiles.length;i++){
                if(srcFiles[i].getName().endsWith(".zip")) {
                    //防止形成死循环
                    continue;
                }
                if(srcFiles[i].isDirectory()){  
                    File[] files = srcFiles[i].listFiles();
                    String srcPath = srcFiles[i].getName();
                    srcPath = srcPath.replaceAll("\\*", "/");
                    if(!srcPath.endsWith("/")){
                        srcPath+="/";
                    }
                    out.putNextEntry(new ZipEntry(path+srcPath));
                    ZipFiles(out,path+srcPath,files);
                }
                else{
                    FileInputStream in = new FileInputStream(srcFiles[i]);
                    System.out.println(path + srcFiles[i].getName());  
                    out.putNextEntry(new ZipEntry(path + srcFiles[i].getName()));
                    int len;  
                    while((len=in.read(buf))>0){  
                        out.write(buf,0,len);
                    }  
                    out.closeEntry();
                    in.close();
                }  
            }  
        } catch (Exception e) {
            e.printStackTrace();
        }  
    } 
    
    public static void ZipFiles(File zip,String path,File... srcFiles) throws IOException {
        if(zip.exists()) {
            zip.delete();
        }
        ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zip));
        ZipFiles(out,path,srcFiles);
        out.close();
    }

}

 

3.解压

思路:获取压缩文件的ZipEntry,对每个ZipEntry进行恢复操作。创建同名文件获取数据流写入文件。

代码实现:

 

package com.wxisme.demo;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

/**
 *解压文件
 *@author wxisme
 *@time 2015-10-5 下午9:18:57
 */
public class Decompression {
    
    /**
     * 解压
     * @param zipFilePath 待解压文件的路径
     * @param unzipFilePath 解压后的文件存储路径
     * @throws Exception
     */
    public static void unzip(String zipFilePath, String unzipFilePath) throws Exception {  
        File zipFile = new File(zipFilePath);
        
        
        //创建解压缩文件保存的路径  
        File unzipFileDir = new File(unzipFilePath);
        if (!unzipFileDir.exists() || !unzipFileDir.isDirectory()) {  
            unzipFileDir.mkdirs();
        }
         
        //开始解压  
        ZipEntry entry = null;
        String entryFilePath = null, entryDirPath = null;  
        File entryFile = null, entryDir = null;  
        int index = 0, count = 0;  
        byte[] buffer = new byte[1024];  
        BufferedInputStream bis = null;  
        BufferedOutputStream bos = null;  
        ZipFile zip = new ZipFile(zipFile);  
        Enumeration<ZipEntry> entries = (Enumeration<ZipEntry>)zip.entries();  
        //循环对压缩包里的每一个文件进行解压       
        while(entries.hasMoreElements()) {  
            entry = entries.nextElement();  
            //构建压缩包中一个文件解压后保存的文件全路径  
            entryFilePath = unzipFilePath + File.separator + entry.getName();  
            //构建解压后保存的文件夹路径  
            index = entryFilePath.lastIndexOf(File.separator);  
            if (index != -1) {  
                entryDirPath = entryFilePath.substring(0, index);  
            }  
            else {  
                entryDirPath = "";  
            }             
            entryDir = new File(entryDirPath);  
            //如果文件夹路径不存在,则创建文件夹  
            if (!entryDir.exists() || !entryDir.isDirectory()) {  
                entryDir.mkdirs();  
            }  
              
            //创建解压文件  
            entryFile = new File(entryFilePath);  
            if (entryFile.exists()) {  
                //检测文件是否允许删除,如果不允许删除,将会抛出SecurityException  
                SecurityManager securityManager = new SecurityManager();  
                securityManager.checkDelete(entryFilePath);  
                //删除已存在的目标文件  
                entryFile.delete();
            }  
              
            //写入文件  
            bos = new BufferedOutputStream(new FileOutputStream(entryFile));  
            bis = new BufferedInputStream(zip.getInputStream(entry));  
            while ((count = bis.read(buffer, 0, 1024)) != -1) {  
                bos.write(buffer, 0, count);  
            }  
            bos.flush();  
            bos.close();              
        }  
    }

}

 

注意:在压缩文件时,如果压缩路径包含要创建的zip文件就要注意逃过同名的zip文件,否则会造成死循环。

 

转载于:https://www.cnblogs.com/wxisme/p/4856338.html

相关文章:

  • 《自信力~成为更好的自己》晨读笔记
  • Spring aop:decare-parent 为类增加新的方法
  • 在resin配置參数实现JConsole远程监控JVM
  • 同样加班 不同收获(转)
  • 使用Java语言开发微信公众平台(八)——自定义菜单功能
  • SPRING-MVC 访问静态资源
  • IE6下position:fixed不支持问题及其解决方式
  • Erlang库 -- 有意思的库汇总
  • 《大数据算法》一2.3 时间亚线性判定算法概述
  • 获取一个数二进制序列中所有的偶数位和奇数位,分别输出二进制序列
  • Setfocus - IE 需要使用setTimeout
  • linux 文件名编码批量转换
  • zabbix监控:监控windows进程
  • CGAL4.10 / CGAL4.13编译
  • multiMap by angular
  • FastReport在线报表设计器工作原理
  • HTTP--网络协议分层,http历史(二)
  • Javascript 原型链
  • javascript数组去重/查找/插入/删除
  • JS字符串转数字方法总结
  • overflow: hidden IE7无效
  • React的组件模式
  • vue 配置sass、scss全局变量
  • WePY 在小程序性能调优上做出的探究
  • 浮现式设计
  • 基于web的全景—— Pannellum小试
  • 看完九篇字体系列的文章,你还觉得我是在说字体?
  • 利用阿里云 OSS 搭建私有 Docker 仓库
  • 聊聊springcloud的EurekaClientAutoConfiguration
  • 深度学习在携程攻略社区的应用
  • 试着探索高并发下的系统架构面貌
  • 手机端车牌号码键盘的vue组件
  • 算法---两个栈实现一个队列
  • ${factoryList }后面有空格不影响
  • (附源码)springboot宠物管理系统 毕业设计 121654
  • (已解决)vue+element-ui实现个人中心,仿照原神
  • (转)ABI是什么
  • .Net Core 中间件验签
  • .NET HttpWebRequest、WebClient、HttpClient
  • .NET MVC 验证码
  • .NET Remoting学习笔记(三)信道
  • .net 后台导出excel ,word
  • .NET6实现破解Modbus poll点表配置文件
  • .NET国产化改造探索(三)、银河麒麟安装.NET 8环境
  • .NET教程 - 字符串 编码 正则表达式(String Encoding Regular Express)
  • .net中调用windows performance记录性能信息
  • ??如何把JavaScript脚本中的参数传到java代码段中
  • @Responsebody与@RequestBody
  • @RestControllerAdvice异常统一处理类失效原因
  • [ vulhub漏洞复现篇 ] ThinkPHP 5.0.23-Rce
  • [20170728]oracle保留字.txt
  • [BZOJ4010]菜肴制作
  • [C#]OpenCvSharp使用帧差法或者三帧差法检测移动物体
  • [ESP32] 编码旋钮驱动
  • [GDOUCTF 2023]<ez_ze> SSTI 过滤数字 大括号{等