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();
    }
}

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


文章作者: 柏竹
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 柏竹 !
评论
  目录