压缩和解压缩文件(十一)

勿以恶小而为之,勿以善小而不为--------------------------刘备
劝诸君,多行善事积福报,莫作恶

上一章简单介绍了 合并流SequenceInputStream和回退流PushbackInputStream(十),如果没有看过,请观看上一章

一. 压缩和解压缩

生活中,我们常见的有 .zip(Windows系统), .jar, .gzip(Linux系统) 等压缩包。 Java语言,也可以实现 压缩和解压缩的功能 。

一个压缩包:

有图片

data.txt, data2.txt,129.png 都放置在 A.zip 压缩文件下, 它们叫做 ZipEntry,是文件条目。

我们要想压缩文件, 需要用到 ZipOutputStream 类。

压缩的那个文件,如 A.zip ,不能用普通的 File 类进行接收, 而应该用 ZipFile 类。

我们想要解压缩, 那么需要用到 ZipInputStream 类。

所以,压缩和解压缩 需要用到 ZipEntry, ZipOutputStream, ZipFile, ZipInputStream 四个类。

二. 文件条目 ZipEntry

public class ZipEntry implements ZipConstants, Cloneable {

}

父类是 Object.

二.一 方法

二.一.一 构造方法

二.一.一.一 方法
方法作用
ZipEntry​(String name)传入文件的名称,唯一值,不能重复
ZipEntry​(ZipEntry e)传入zipEntry 对象,可以进行嵌套, 压缩文件里面还有压缩文件
二.一.一.二 演示
  public void entryConTest(){

        //第一种方式
        ZipEntry zipEntry=new ZipEntry("压缩文件.txt");

        //第二种方式 
        ZipEntry zipEntry1=new ZipEntry(zipEntry);
    }

一般都采用第一种方式, 直接传入唯一的文件名称。

二.一.二 其他方法

方法作用
boolean isDirectory​()判断是否是目录,如果是目录,就返回true,不是目录,返回false
void setComment​(String comment)设置注释
void setCreationTime​(FileTime time)设置创建的时间
void setSize​(long size)设置文件的大小
void setTime​(long time)设置最后的修改时间
ZipEntry setLastAccessTime​(FileTime time)设置最后的访问时间
ZipEntry setLastModifiedTime​(FileTime time)设置最后的修改时间
String getComment​()获取注释
FileTime getCreationTime​()获取创建时间
FileTime getLastAccessTime​()获取最后访问时间
FileTime getLastModifiedTime​()获取最后修改时间
String getName​() 获取名称
long getSize​()获取大小
long getTime​()获取最后的修改时间

单独的 ZipEntry 是无法存在的,需要与其他的对象关联使用。

三. Zip文件压缩输出流 ZipOutputStream

三.一 方法

三.一.一 构造方法

三.一.一.一 方法
方法作用
ZipOutputStream​(OutputStream out)传入 输出流 outputStream 对象
ZipOutputStream​(OutputStream out, Charset charset)传入输出流和文件编码
三.一.一.二 演示
    @Test
    public void conTest() throws Exception{


        File file=new File("E:"+ File.separator+"ideaWork"+File.separator+"Java2"+File.separator+"fileSrc"
                +File.separator+"jdk91.zip");
        
        ZipOutputStream zipOutputStream=new ZipOutputStream(new FileOutputStream(file));

    }

三.一.二 其他方法

方法作用
void close​()关闭输出流
void setComment​(String comment)设置文件注释
void write​(byte[] b, int off, int len)写数据到字节数组
void putNextEntry​(ZipEntry e)开始编写新的ZIP文件条目,并将流定位到条目数据的开头。

三.二 演示 ZipOutputStream

三.二.一 压缩单个文件

@Test
    public void zip1Test() throws Exception{

        //找到要压缩的那个文件, 作输入流
        File file=new File("E:"+ File.separator+"ideaWork"+File.separator+"Java2"+File.separator+"fileSrc"
                +File.separator+"jdk9.CHM");

        InputStream inputStream=new FileInputStream(file);

        //定义要压缩到的那个文件为 输出流

        File outFile=new File("E:"+ File.separator+"ideaWork"+File.separator+"Java2"+File.separator+"fileSrc"
                +File.separator+"jdk9.zip");
        OutputStream outputStream=new FileOutputStream(outFile);

        //定义ZipOutputStream, 传入目标文件的outputStream

        ZipOutputStream zipOutputStream=new ZipOutputStream(outputStream);

        //放置压缩里面的内容,这样就算是放置进去了。
        zipOutputStream.putNextEntry(new ZipEntry(file.getName()));

        //设置注释

        zipOutputStream.setComment("这是什么玩意 ");

        byte[] bytes=new byte[1024];

        int len=-1;

        //读取文件到字节数组
        while((len=inputStream.read(bytes))!=-1){
            // 进行压缩,写入字节数组
            zipOutputStream.write(bytes,0,len);
        }

        //关闭
        zipOutputStream.close();
        outputStream.close();
        inputStream.close();

    }

压缩前:

有图片

运行程序,再次查看文件系统

有图片

点进去该文件 jdk9.zip,可以进行查看

有图片

注意: 压缩文件时,也可以放置多个文件进去。

 zipOutputStream.putNextEntry(new ZipEntry(file.getName()));
	zipOutputStream.putNextEntry(new ZipEntry(file1.getName()));
	zipOutputStream.putNextEntry(new ZipEntry(fil2.getName()));
	zipOutputStream.putNextEntry(new ZipEntry(file3.getName()));

这样 jdk9.zip 里面,就可以有四个文件了。

三.二.二 压缩文件夹

将 data,data2,data3,data4 复制一份到 a 文件夹下。
在这里插入图片描述

 @Test
    public void zip2Test() throws Exception{

        //1. 定义压缩输入 的目录

        File inFile=new File("E:"+ File.separator+"ideaWork"+File.separator+"Java2"+File.separator+"fileSrc"
                +File.separator+"a");

        InputStream inputStream=null;

        //2.定义 压缩输出文件

        File outFile=new File("E:"+ File.separator+"ideaWork"+File.separator+"Java2"+File.separator+"fileSrc"
                +File.separator+"a.zip");


        ZipOutputStream zipOutputStream=new ZipOutputStream(new FileOutputStream(outFile));

        zipOutputStream.setComment("压缩文件夹");

        //如果文件是一个目录的话
        if(inFile.isDirectory()){


            //查询该目录下的文件
            File[] fileList=inFile.listFiles();


            for(File f:fileList){

                if(f.isDirectory()){
                    continue;
                }
                //为每一个文件设置一个 输入流
                inputStream=new FileInputStream(f);

               //设置压缩文件条目
                zipOutputStream.putNextEntry(new ZipEntry(f.getName()));


                //
                byte[] bytes=new byte[1024];

                int len=-1;

                while((len=inputStream.read(bytes))!=-1){
                    // 进行压缩
                    zipOutputStream.write(bytes,0,len);
                }

            }

            //关闭
            zipOutputStream.close();
            inputStream.close();



        }else{ //是普通文件


            inputStream=new FileInputStream(inFile);

            zipOutputStream.putNextEntry(new ZipEntry(inFile.getName()));

            byte[] bytes=new byte[1024];

            int len=-1;

            while((len=inputStream.read(bytes))!=-1){
                // 进行压缩
                zipOutputStream.write(bytes,0,len);
            }

            //关闭
            zipOutputStream.close();
            inputStream.close();
        }
    }

运行程序, 查看文件系统

有一个 a.zip 压缩文件,里面有那四个文件。

有图片

四. 压缩文件 ZipFile

public class ZipFile implements ZipConstants, Closeable {

}

四.一 方法

四.一.一 构造方法

四.一.一.一 方法
方法作用
ZipFile​(File file)传入压缩文件
ZipFile​(String name)传入压缩文件的名称
四.一.一.二 演示
   @Test
    public void zipFileConTest() throws Exception{

        //第一种方式,传入文件
        File file=new File("E:"+ File.separator+"ideaWork"+File.separator+"Java2"+File.separator+"fileSrc"
                +File.separator+"a.zip");

        ZipFile zipFile=new ZipFile(file);

        //第二种方式,传入文件的路径
        String path="E:"+ File.separator+"ideaWork"+File.separator+"Java2"+File.separator+"fileSrc"
                +File.separator+"a.zip";

        ZipFile zipFile1=new ZipFile(path);
    }

四.一.二 其他方法

方法作用
int size​()获取文件的大小
String getName​()获取文件的名称
String getComment​()获取注释
ZipEntry getEntry​(String name)根据名称获取 zipEntry. name是我们原先就要知道的
InputStream getInputStream​(ZipEntry entry)根据 zipEntry 获取 inputStream流
Enumeration<? extends ZipEntry> entries​()获取该压缩文件夹下的 zipEntry 集合

四.二 演示压缩文件 ZipFile

四.二.一 获取压缩文件的基本信息

 @Test
    public void zipFileTest() throws Exception{
        File file=new File("E:"+ File.separator+"ideaWork"+File.separator+"Java2"+File.separator+"fileSrc"
                +File.separator+"a.zip");

        ZipFile zipFile=new ZipFile(file);

        System.out.println("获取文件注释:"+zipFile.getComment());

        System.out.println("文件名称:"+zipFile.getName());
        System.out.println("文件大小:"+zipFile.size());

        //根据名称,获取 zipEntry
        ZipEntry zipEntry=zipFile.getEntry("data.txt");
        System.out.println("输出名称:"+zipEntry.getName());

        //根据 zipEntry 获取 输入流
        InputStream inputStream=zipFile.getInputStream(zipEntry);


        System.out.println("*************************");
        //获取压缩文件下的所有条目
        Enumeration<? extends ZipEntry> entries = zipFile.entries();

       while(entries.hasMoreElements()){

           ZipEntry temp=entries.nextElement();

           System.out.println("输出名称:"+temp.getName());
       }


    }

运行程序, 控制台打印输出:

有图片

四.二.二 根据条目文件名称,解压缩单个文件

@Test
    public void zipFile1Test() throws Exception{
        //1. 先定义好输出流
        File file=new File("E:"+ File.separator+"ideaWork"+File.separator+"Java2"+File.separator+"fileSrc"
                +File.separator+"解压缩单个文件.txt");

        OutputStream outputStream=new FileOutputStream(file);


        //找到压缩文件
        File inputFile=new File("E:"+ File.separator+"ideaWork"+File.separator+"Java2"+File.separator+"fileSrc"
                +File.separator+"a.zip");

        ZipFile zipFile=new ZipFile(inputFile);

        //根据名称,获取 ZipEntry。 只解压缩 a.zip 中的 data.txt 文件

        ZipEntry zipEntry=zipFile.getEntry("data.txt");

        //获取输入流

        InputStream inputStream=zipFile.getInputStream(zipEntry);

        byte[] bytes=new byte[1024];

        int len=-1;
        //读出
        while((len=inputStream.read(bytes))!=-1){
            //写入
            outputStream.write(bytes,0,len);
        }


        outputStream.close();
        inputStream.close();
    }

运行程序,查看文件系统

有图片

内容也是有的,与 a.zip 文件下的 data.txt 内容一致。

现在解压缩,我们知道要解压缩的文件名称,然而大部分情况下,是不知道要解压缩的文件名称的。

五. ZipInputStream

解压缩文件的输入流。

五.一 方法

五.一.一 构造方法

五.一.一.一 方法
方法作用
ZipInputStream​(InputStream in)传入输入流
ZipInputStream​(InputStream in, Charset charset)传入输入流和字符编码
五.一.一.二 举例
 @Test
    public void zipInputStreamConTest() throws Exception{
        //File inputFile=new File("E:"+ File.separator+"ideaWork"+File.separator+"Java2"+File.separator+"fileSrc"
         //       +File.separator+"jdk91.zip");

        File inputFile=new File("E:"+ File.separator+"ideaWork"+File.separator+"Java2"+File.separator+"fileSrc"
                +File.separator+"a.zip");

        InputStream inputStream=new FileInputStream(inputFile);


		// 传入输入流 
        ZipInputStream zipInputStream=new ZipInputStream(inputStream);

       

  }

五.一.二 其他方法

方法作用
void close​()关闭此输入流并释放与流相关联的任何系统资源。
void closeEntry​()关闭当前的ZIP条目,并定位流以读取下一个条目。
ZipEntry getNextEntry​()读取下一个ZIP文件条目,并将流定位在条目数据的开头。放置到while中循环判断
int read​(byte[] b, int off, int len)从当前ZIP条目读取到字节数组。
protected ZipEntry createZipEntry​(String name)为指定的条目名称创建一个新的 ZipEntry对象。

五.二. 举例 ZipInputStream

五.二.一 解压缩文件

 //解压缩文件
    @Test
    public void zipFile2Test() throws Exception{
        //1. 先定义好解压缩的文件
        File file=new File("E:"+ File.separator+"ideaWork"+File.separator+"Java2"+File.separator+"fileSrc"
                +File.separator+"c");

        //找到压缩文件
        File inputFile=new File("E:"+ File.separator+"ideaWork"+File.separator+"Java2"+File.separator+"fileSrc"
                +File.separator+"a.zip");

        InputStream inputStream=new FileInputStream(inputFile);

        //输入流
        ZipInputStream zipInputStream=new ZipInputStream(inputStream);

        //压缩文件
        ZipFile zipFile=new ZipFile(inputFile);

        //定义每一个文件

        ZipEntry zipEntry=null;

        //先看父存不在
        if(file.getParent()==null){
            file.mkdirs();
        }


        while((zipEntry=zipInputStream.getNextEntry())!=null){

            //说明有子。

            String name=zipEntry.getName();

            //解压到当前的目录。

            File newFile=new File(file,name);

            if(!newFile.getParentFile().exists()){
                newFile.getParentFile().mkdirs();
            }

            //创建当前文件
            if(!newFile.exists()){
                newFile.createNewFile();
            }
            //获取每一个流,根据 zipEntry
            InputStream inputStream1=zipFile.getInputStream(zipEntry);

            //替换型
            OutputStream newOutputStream=new FileOutputStream(newFile);


            byte[] bytes=new byte[1024];

            int len=-1;

            while((len=inputStream1.read(bytes))!=-1){

                //写入
                newOutputStream.write(bytes,0,len);

            }

            newOutputStream.close();

            inputStream1.close();
        }

        System.out.println("文件夹解压缩成功");
        zipInputStream.close();
        inputStream.close();

    }

现在,系统里面没有 c 文件夹。

运行程序,查看文件系统,解压缩成功。

有图片


谢谢您的观看,如果喜欢,请关注我,再次感谢 !!!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

两个蝴蝶飞

你的鼓励,是老蝴蝶更努力写作的

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值