IO_File类使用:文件压缩与解压

ZipOutputStream
实现文件的压缩类
ZipOutputStream(OutputStream out) 创建新的zip输出流
void putNextEntry(ZipEntry e)     ZipOutputStream类的方法开始写入新的zip文件条目并将流定位到条目数据的开始处
ZipEntry(String name)             ZipEntry类的构造使用指定名称创建新的zip条目,如test/mm.jpg,test/gg.jpg


ZipInputStream
实现文件的解压类
ZipInputStream(InputStream in)    创建新的zip输入流
ZipEntry getNextEntry()           ZipInputStream类的方法getNextEntry返回ZipEntry类型读取下一个zip文件条目并将流定位到该条目数据的开始处

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

public class CompressAndDemopressDemo {

    public static void main(String[] args) {
        //compress("E:\\Java_IO\\hudechao.zip",new File("E:\\Java_IO\\hudechao"));
        decompress("E:\\Java_IO\\hudechao.zip","E:\\Java_IO\\hudechao2");
    }
    
    //文件压缩,参数zipFileName表示压缩后的压缩名称,targetFile表示需要被要锁的源文件
    public static void compress(String zipFileName,File targetFile) {
        try {
            ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFileName)); //实现压缩
            BufferedOutputStream bos = new BufferedOutputStream(zos);                     //压缩文件的输出流
            zip(bos,zos,targetFile,targetFile.getName());   //所以实现压缩的实际方法都需要这两个参数,zos,bos,targetFile.getName()是为了获取每个条目的唯一路径ZipEntry
            bos.close();
            zos.close();
            
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void zip(BufferedOutputStream bos, ZipOutputStream zous, File targetFile, String name) throws IOException {
        if(targetFile.isDirectory()) {                     //如果需要被压缩的源文件是个目录时,需要对里面的每个文件生成条目-ZipEntry()
            File[] files = targetFile.listFiles();
            if(files.length==0) {                          //如果是个空目录时,就直接生成一个条目-ZipEntry()
                zous.putNextEntry(new ZipEntry(name+"/")); //这里name是被压缩的文件的名称,为什么带上“/”,因为windows里目录文件后面会跟"/"
            }
            for(File f:files) {                            //如果是个目录且目录里有文件,就要递归判断里面的文件是目录还是文件
                zip(bos,zous,f,name+"/"+f.getName());      //这里 name+"/"+f.getName() 就如同 test/mm.jpg,所以"/" 是有必要的;在把 name+"/"+f.getName()当做name作为参数递归调用
            }
        }else {
            zous.putNextEntry(new ZipEntry(name));         //这里的name是:1、本身传入的参数name就是个文件不是目录,2、当是目录时,经过递归调用时的 name+"/"+f.getName()
            InputStream in = new FileInputStream(targetFile);
            BufferedInputStream bis = new BufferedInputStream(in);
            int len = -1;
            byte[] bytes = new byte[1024];
            while((len=bis.read(bytes))!=-1) {
                bos.write(bytes,0,len);
            }
            bis.close();
        }
        
    }
    
    
     /**
     * ?不能对在windows里手动压缩的zip包进行解压?
     * 文件的解压
     * 如下方法只能对压缩包里的是非空目录才能解压
     */
    public static void decompress(String targetFileName,String parent) {                  //参数targetFileName表示需要解压的源文件,parent表示解压到该目录下
        try {
            ZipInputStream zis = new ZipInputStream(new FileInputStream(targetFileName)); //解压文件的输入流
            ZipEntry entry = null;
            File file = null;
            while((entry=zis.getNextEntry())!=null && !entry.isDirectory()) {             //循环的条件是:待解压文件的里面的条目不为空,且条目是个文件时
                file = new File(parent,entry.getName());      //当该条目是文件时就对该文件创建File,参数时它的父目录和自己本身的名称如(test,mm,jpg),所以它的路径是test/mm.jpg
                if(!file.exists()) {
                    new File(file.getParent()).mkdirs();      //这里判断file是否存在,解压的时候file(包括文件和目录)一般肯定是在新目录里不存在的,
                                                              //所以它的上级目录时肯定要在的,所以就必须得先创建它的上级目录;然后流才会自动在该创建好的上级目录里创建File
                }
                OutputStream out = new FileOutputStream(file);//解压后的输出流,bytes数组里的条目值写入file里
                BufferedOutputStream bos = new BufferedOutputStream(out);
                int len = -1;
                byte[] bytes = new byte[1024];
                while((len=zis.read(bytes))!=-1) {  //先由解压输入流读进来每个条目,读进bytes数据存储
                    bos.write(bytes,0,len);         //再由解压输出流写出去
                }
                bos.close();
                System.out.println(file+"解压成功");
            }
            zis.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    /**
     * 文件的解压
     * 1、对于压缩包里是空目录的也可解压;
     * 2、对于压缩包里即有目录又有文件的也可解压;
     */
    public static void decompress2(String targetFileName,String parent) {  //targetFileName表示待解压的文件,parent表示解压后存在目录的父级目录
        try {
            ZipInputStream zis = new ZipInputStream(new FileInputStream(targetFileName));
            BufferedInputStream bis = new BufferedInputStream(zis);
            ZipEntry entry = null;
            
            while((entry=zis.getNextEntry())!=null) {             //首先条目不能为空才能解压的即表示压缩包里是有东西存在的;如果为空那么说明这个压缩包格式是异常的
                if(entry.isDirectory()) {                         //如果条目是个目录,那么直接创建这个目录,就表示解压了这个压缩包了
                    File file = new File(parent,entry.getName()); //当该条目是文件时就对该文件创建File,参数时它的父目录和自己本身的名称如(test,mm,jpg),所以它的路径是test/mm.jpg
                    file.mkdirs();
                    System.out.println(file+"解压完成");
                }else {                                      
                    File files = new File(parent,entry.getName()); //如果不是个目录,即是个文件的话,那么就要创建File类的对象了
                    if(!files.exists()) {                          //解压的文件一般肯定事先不存在的
                        new File(files.getParent()).mkdirs();      //所以得先创建它的父级目录,因为它是个文件,那么它的父级一定是个目录了(只有目录里才能存文件的嘛);然后流才会自动在该创建好的上级目录里创建File
                    }
                    OutputStream ous = new FileOutputStream(files);//这里的输出流是经上面文件的父目录创建完成后,才会去执行,所以是跟上面的if(!files.exists())是串行的,只有先创建了目录,才能在该目录里创建文件流
                    BufferedOutputStream bos = new BufferedOutputStream(ous); //所以不是在else的语句里,如果是else语句里,那么程序就不会执行到该代码了,因为else判断存在时才会执行
                    int len = -1;
                    byte[] bytes = new byte[1024];
                    while((len=bis.read(bytes))!=-1) {
                        bos.write(bytes,0,len);
                    }
                    bos.close();
                    System.out.println(files+"解压完成");
                }
            }
            bis.close();
            
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
}

猜你喜欢

转载自blog.csdn.net/weixin_33805557/article/details/87073899
今日推荐