java 实现 文件Zip解压缩

ZIP文件条目

Class ZipEntry

java.lang.Object
java.util.zip.ZipEntry

ZipEntry类 产生的对象,用来代表代表ZIP压缩文件的进入点

构造方法

ZipEntry(String name)

ZipEntry(ZipEntry e)

name:条目名称
e:zip条目对象

由于方法过多自行查JDK文档 ,后续有代码例子有说明

压缩流(压缩文件)

Class ZipOutputStream

java.lang.Object
java.io.OutputStream
java.io.FilterOutputStream
java.util.zip.DeflaterOutputStream
java.util.zip.ZipOutputStream

大致流程

  1. 创建被压缩的对象 和 压缩包的对象
  2. 创建 字节输出流 和 压缩输出流
  3. 为文件创建ZipEntry条目
  4. 将读取的数据通过输出流写入到硬盘中
  5. 完成压缩

构造方法

ZipOutputStream(OutputStream out) 

out:输出流

方法

修饰符 方法 说明
void close() 关闭流
void closeEntry() 关闭当前的ZIP条目,并定位流以写入下一个条目
void finish() 完成编写ZIP输出流的内容,而不关闭底层流
void putNextEntry(ZipEntry e) 开始编写新的ZIP文件条目,并将流定位到条目数据的开头
void setComment(String comment) 设置ZIP文件注释
void write(byte[] b, int off, int len) 将字节数组写入当前的ZIP条目数据

例子1 (老师讲解的例题)

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

public class Demo {
    
    
    
    static void compress(){
    
    
        //创建被压缩的对象
        File source = new File("E:\\png\\");
        //创建压缩包的对象
        File target = new File("E:\\mr.zip");
        
        //try括号内的资源会在try语句结束后自动释放,前提是这些可关闭的资源必须实现
        //创建字节输出流、压缩输出流
        try(FileOutputStream fis = new FileOutputStream(target);
            ZipOutputStream zos = new ZipOutputStream(fis)){
    
    
            
            //判断是否是文件夹
            if(source.isDirectory()){
    
    
                //遍历文件夹的文件
                for(File f : source.listFiles()){
    
    
                    addEntry(zos , "" , f);
                }
            }else{
    
    
                addEntry(zos,"",source);
            }
            
        }catch (Exception e){
    
    
            e.printStackTrace();
        }
        
    }
    
    /*
    *
    *   该方法用来写入文件数据 和 重新遍历文件夹
    * 方法参数:
    *   zos:压缩流
    *   base: 文件在压缩包中的路径
    *   source:被压缩的文件
    *
    *  */
    static void addEntry(ZipOutputStream zos , String base , File source){
    
    
        //判断是否是文件夹
        if (source.isDirectory()){
    
    //判断为文件夹
            
            //遍历文件夹的文件
            for (File file : source.listFiles()){
    
    
                /*
                *   参数2:
                *       base:文件路径
                *       source.getName():文件夹名称
                *       File.separator:分隔符( \\ 和 / )
                *
                * */
                addEntry(zos , base + source.getName() + File.separator , file);
            }
            
        }else{
    
    //判断为文件
            
            //写入压缩流
            
            //创建缓冲区
            byte[] b = new byte[1024];
            //创建 字节输入流
            //source 是文件
            try(FileInputStream fis = new FileInputStream(source)) {
    
    
                //判断开关
                int count = -1;
                
                //putNextEntry()方法开始编写新的ZIP文件条目,并将流定位到条目数据的开头
                //实例化ZIP文件条目 条目路径及名称
                zos.putNextEntry(new ZipEntry(base + source.getName()));
                // 读取文件 直到读完
                while((count = fis.read(b)) != -1){
    
    
                    //写入压缩流。 b 缓冲内容
                    zos.write(b , 0 , count);
                    //刷新流
                    zos.flush();
                }
                zos.closeEntry();
            }catch (Exception e){
    
    
                e.printStackTrace();
            }
            
        }
        
    }
    
    public static void main(String[] args) {
    
    
        compress();
    }
}

例子2 (个人写的例题)

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;

public class Demo2 {
    
    
    
    //压缩方法
    static void Compression(){
    
    
        
        
        File fwj = new File("E:\\png\\");
        File target = new File("E:\\mr2.zip");
    
        FileOutputStream fout = null;
        ZipOutputStream zout = null;
        
        try {
    
    
            fout = new FileOutputStream(target);
            zout = new ZipOutputStream(fout);
            
            //进行压缩的方法
            //参数2为空,因从压缩包里的根路径开始
            addEntry(zout,"",fwj);
            
        }catch (Exception e){
    
    
            e.printStackTrace();
        }finally {
    
    
            try {
    
    
                
                if (zout != null){
    
    
                    zout.close();
                }
        
                if (fout != null){
    
    
                    fout.close();
                }
                
            } catch (Exception e) {
    
    
                e.printStackTrace();
            }
    
        }
    }
    
    /*
     *
     *   该方法用来写入文件数据 和 重新遍历文件夹
     * 方法参数:
     *   zos:压缩流
     *   base: 文件在压缩包中的路径
     *   source:被压缩的文件
     *
     *  */
    static void addEntry(ZipOutputStream zos , String base , File source){
    
    
    
        //判断是否是文件夹
        if (source.isDirectory()){
    
    
                //遍历文件夹
                for (File f : source.listFiles()){
    
    
                    /*
                     *   参数2:
                     *       base:文件路径
                     *       source.getName():文件夹名称
                     *       File.separator:分隔符( \\ 和 / )
                     *       文件路径
                     * */
                    addEntry(zos , base+source.getName()+File.separator , f);
                }
                
        }else{
    
    
            
            //创建 字节输入流
            FileInputStream finp = null;
            
            try{
    
    
                //字节输入流
                finp = new FileInputStream(source);
                //创建条目
                ZipEntry ze = new ZipEntry(base+source.getName());
                //新的ZIP文件条目,并将流定位到条目数据的开头
                zos.putNextEntry(ze);
                
                //判断变量
                int count = -1;
                //创建缓冲区
                byte[] b = new byte[1024];
    
                // 读取文件 直到读完
                while((count = finp.read(b)) != -1){
    
    
                    //写入压缩流。 b 缓冲内容
                    zos.write(b , 0 , count);
                    //刷新流
                    zos.flush();
                }
                //关闭当前的ZIP条目,并定位流以写入下一个条目
                zos.closeEntry();
                
            }catch (Exception e){
    
    
                e.printStackTrace();
            }finally {
    
    
                try {
    
    
                    if (finp != null){
    
    
                        finp.close();
                    }
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
            
        }
        
    }
    
    public static void main(String[] args) {
    
    
        Compression();
    }
}

压缩前提要确定要压缩的 文件夹 或 文件 ,还有压缩后的路径(带名称)

解压流(解压文件)

Class ZipInputStream
java.lang.Object
java.io.InputStream
java.io.FilterInputStream
java.util.zip.InflaterInputStream
java.util.zip.ZipInputStream

大致流程

  1. 创建被压缩的对象 和 压缩包的对象
  2. 创建 字节输入流 和 压缩输入流
  3. 遍历 字节输入流 中的 压缩包里的条目(ZipEntry条目)
  4. 按照压缩包里的目条 对应的文件名创建
  5. 创建 字节输出流写入
  6. 将 输入流 读取的数据通过 字节输出流 写入到硬盘中
  7. 完成解压

构造方法

ZipInputStream(InputStream in)

in:输出流

方法

修饰符 方法 说明
int available() 是否读取完目前指定的数据,读取完返回1,否则为0
void close() 关闭流
void closeEntry() 关闭当前的ZIP条目,并定位流以读取下一个条目
ZipEntry createZipEntry(String name) 为指定的条目名称创建一个新的 ZipEntry对象
ZipEntry getNextEntry() 读取下一个ZIP文件条目,并将流定位在条目数据的开头
int read(byte[] b, int off, int len) 从当前ZIP条目读取到字节数组
long skip(long n) 跳过当前ZIP条目中指定的字节数
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.ZipInputStream;

public class Demo4 {
    
    
    
    //压缩方法
    static void Compression(){
    
    
    
        //解压路径及解压后的文件夹名称
        File dir = new File("E:\\nn");
        //压缩包的路径
        File source = new File("E:\\mr2.zip");
        //创建空条目
        ZipEntry entry = null;
        FileInputStream fis = null;
        ZipInputStream zis = null;
        
        try{
    
    
        
            fis = new FileInputStream(source);
            zis = new ZipInputStream(fis);
            
            while (true){
    
    
    
                //获取下一个ZIP文件条目,并将流定位在条目数据的开头
                entry = zis.getNextEntry();
                //获取完为空 或 第一次获取失败 跳出循环
                if (entry == null){
    
    
                    break;
                }
                //文件夹跳过本次循环
                if (entry.isDirectory()){
    
    
                    continue;
                }
    
                //创建文件
                // dir:解压目的地文件夹
                File f = new File(dir , entry.getName());
    
                /*
                 *
                 * getParentFile()方法 返回指定父路径的目录(文件),没有则空(null)
                 * exists()方法 是否存在该文件
                 * mkdirs()方法 创建路径名命名的目录,包括任何必需但不存在的父目录
                 *
                 * */
    
                //安全代码 ,创建压缩包里的文件夹
                if (!f.getParentFile().exists()){
    
    
                    f.getParentFile().mkdirs();
                }
    
                int count = -1;
                byte[] buf = new byte[1024];
                //输出流
                FileOutputStream fos = new FileOutputStream(f);
                //压缩流循环读取 压缩包中的文件 直到读完
                while((count = zis.read(buf)) != -1){
    
    
                    //写入
                    fos.write(buf , 0 , count);
                    //流刷新(提升效率)
                    fos.flush();
                }
                //关闭流
                fos.close();
                //关闭本次条目,跳到下一个
                zis.closeEntry();
            }
        
        }catch (Exception e){
    
    
            e.printStackTrace();
        }finally {
    
    
            
            if (zis != null){
    
    
                try {
    
    
                    zis.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
            if(fis != null){
    
    
                try {
    
    
                    fis.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
            
        }
        
    }
    
    public static void main(String[] args) {
    
    
        Compression();
    }
}

以上是个人学习后写出来的代码分享,如果有问题可在下面留言!

猜你喜欢

转载自blog.csdn.net/weixin_45963193/article/details/107412589