Java实现zip文件压缩与解压缩--附完整代码

Java实现文件压缩与解压缩-----zip

  • 1 基本概念
  • 2 zip压缩
    • 2.1 zip压缩代码实现
    • 2.2 zip压缩代码改进
  • 3 zip解压
    • 3.1 zip不完美实现
    • 3.2 zip解压完美实现
  • 4 FileZip.class 实现.zip压缩与解压

Java中实现zip的压缩与解压缩

1 基本概念

  1. ZipOutputStream 实现文件的压缩
  • ZipOutputStream (OutputStream out) 创建新的zip输出流
  • void putNextEntry(ZipEntry e) 开始写入新的zip文件条目并将流定位到条目数据的开始处
    条目指的是一个文件夹下的多个文件。
  • ZipEntry(String name) 使用指定名称创建新的zip条目
  1. ZipIutputStream实现文件的解压
  • ZipIutputStream (IutputStream out) 创建新的zip输入流
  • ZipEntry getNextEntry()读取下一个zip条目并将流定位到该条目数据的开始处

2 zip压缩

2.1 zip压缩代码实现

  1. 程序完整代码
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class Uzip {
    /**
     * 压缩
     */

    public static void zip(String input, String output, String name) throws Exception {
    //要生成的压缩文件
        ZipOutputStream out = new ZipOutputStream(new FileOutputStream(output));
        String[] paths = input.split("\\|");
        File[] files = new File[paths.length];
        byte[] buffer = new byte[1024];
        for (int i = 0; i < paths.length; i++) {
            files[i] = new File(paths[i]);
        }
        for (int i = 0; i < files.length; i++) {
            FileInputStream fis = new FileInputStream(files[i]);
            if (files.length == 1 && name != null) {
                out.putNextEntry(new ZipEntry(name));
            } else {
                out.putNextEntry(new ZipEntry(files[i].getName()));
            }
            int len;
            // 读入需要下载的文件的内容,打包到zip文件
            while ((len = fis.read(buffer)) > 0) {
                out.write(buffer, 0, len);
            }
            out.closeEntry();
            fis.close();
        }
        out.close();
    }

    public static void main(String[ ] args){
        try {
            zip("E:\\Testzip\\test\\ytt.html","E:\\Test.zip","testytt");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

maven依赖:

    
        org.apache.commons
        commons-compress
        1.12
    
  1. 运行程序:

Java实现zip文件压缩与解压缩--附完整代码_第1张图片

3.程序解读:

  • ZipEntry(String name) 只能实现一个固定条目的压缩,也就是你压缩什么就得写仔细它的路径,多个子文件压缩写法如下:
public static void main(String[ ] args){
        try {
            zip("E:\\Testzip\\test\\ytt.html|E:\\Testzip\\uugg.html","E:\\Test.zip",null);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

注意

一定要写全E:\\Testzip\\test\\ytt.html,如果写E:\\Testzip\\test\\ytt会报错,报错信息无访问权限。

String input :定义的是待压缩文件的条目。

String output:定义得到的压缩文件包.zip的名字。

String name:定义压缩后的条目的名字,如果与压缩前保持一致,定义name为null即可。

此程序无法实现对空文件夹的压缩。

2.2 zip压缩代码改进

改进的代码可以实现对任意文件的压缩,注意要写全文件类型,比如ytt.html,不允许省略.html。

import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * date: 2019/07/26
 * writed by yangtingting
 */
public class FileZip {
    /**
     * zip文件压缩
     * @param inputFile 待压缩文件夹/文件名
     * @param outputFile 生成的压缩包名字
     */

    public static void ZipCompress(String inputFile, String outputFile) throws Exception {
        //创建zip输出流
        ZipOutputStream out = new ZipOutputStream(new FileOutputStream(outputFile));
        //创建缓冲输出流
        BufferedOutputStream bos = new BufferedOutputStream(out);
        File input = new File(inputFile);
        compress(out, bos, input,null);
        bos.close();
        out.close();
    }
    /**
     * @param name 压缩文件名,可以写为null保持默认
     */
    //递归压缩
    public static void compress(ZipOutputStream out, BufferedOutputStream bos, File input, String name) throws IOException {
        if (name == null) {
            name = input.getName();
        }
        //如果路径为目录(文件夹)
        if (input.isDirectory()) {
            //取出文件夹中的文件(或子文件夹)
            File[] flist = input.listFiles();

            if (flist.length == 0)//如果文件夹为空,则只需在目的地zip文件中写入一个目录进入
            {
                out.putNextEntry(new ZipEntry(name + "/"));
            } else//如果文件夹不为空,则递归调用compress,文件夹中的每一个文件(或文件夹)进行压缩
            {
                for (int i = 0; i < flist.length; i++) {
                    compress(out, bos, flist[i], name + "/" + flist[i].getName());
                }
            }
        } else//如果不是目录(文件夹),即为文件,则先写入目录进入点,之后将文件写入zip文件中
        {
            out.putNextEntry(new ZipEntry(name));
            FileInputStream fos = new FileInputStream(input);
            BufferedInputStream bis = new BufferedInputStream(fos);
            int len;
            //将源文件写入到zip文件中
            byte[] buf = new byte[1024];
            while ((len = bis.read(buf)) != -1) {
                bos.write(buf,0,len);
            }
            bis.close();
            fos.close();
        }
    }
    public static void main(String[] args) {
        try {
            ZipCompress("D:\\Test", "D:\\TestbyYTT.zip");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}


3 zip解压

3.1 zip不完美实现

  1. 这个网上有很多代码的,比如:
package file;
 
import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
 
public class Decompressing {
    public static void main(String[] args) {
        File file = new File("E:\\hello.zip");//当前压缩文件
        ZipInputStream zin;//创建ZipInputStream对象
        try {
            ZipFile zipFile = new ZipFile(file);//创建压缩文件对象
            zin = new ZipInputStream(new FileInputStream(file));//实例化对象,指明要解压的文件
            ZipEntry entry ;
            while (((entry=zin.getNextEntry())!=null)&& !entry.isDirectory()){//如果entry不为空,并不在同一个目录下
                File tmp = new File(entry.getName());//解压出的文件路径
                if (!tmp.exists()){//如果文件不存在
                    tmp.getParentFile().mkdirs();//创建文件父类文件夹路径
                    OutputStream os = new FileOutputStream(tmp);//将文件目录中的文件放入输出流
                    //用输入流读取压缩文件中制定目录中的文件
                    InputStream in = zipFile.getInputStream(entry);
                    int count = 0;
                    while ((count = in.read())!=-1){//如有输入流可以读取到数值
                        os.write(count);//输出流写入
                    }
                    os.close();
                    in.close();
                }
                zin.closeEntry();
                System.out.println(entry.getName()+"解压成功");
            }
            zin.close();
 
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
 
}

以上代码运行时会抛出异常!!!!!!!!!

做出相应更改:

import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

/**
 * date:2019/7/26
 * writed by yangtingting
 */

public class zipUncompress {
    /**
     * zip文件解压
     *
     * @param inputFile   待解压文件夹/文件
     * @param destDirPath 解压路径
     */
    public static void zipUncompress(String inputFile, String destDirPath) throws Exception {
        File srcFile = new File(inputFile);//获取当前压缩文件
        // 判断源文件是否存在
        if (!srcFile.exists()) {
            throw new Exception(srcFile.getPath() + "所指文件不存在");
        }
        //开始解压
        //构建解压输入流
        ZipInputStream zIn = new ZipInputStream(new FileInputStream(srcFile));
        ZipEntry entry = null;
        File file = null;
        while ((entry = zIn.getNextEntry()) != null) {
            if (!entry.isDirectory()) {
                file = new File(destDirPath, entry.getName());
                if (!file.exists()) {
                    new File(file.getParent()).mkdirs();//创建此文件的上级目录
                }
                OutputStream out = new FileOutputStream(file);
                BufferedOutputStream bos = new BufferedOutputStream(out);
                int len = -1;
                byte[] buf = new byte[1024];
                while ((len = zIn.read(buf)) != -1) {
                    bos.write(buf, 0, len);
                }
                // 关流顺序,先打开的后关闭
                bos.close();
                out.close();
            }
        }
    }
    public static void main(String[] args) {
        try {
            zipUncompress("D:\\ytt.zip", "D:\\ytt的解压文件\\");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

完美运行!!!

3.2 zip解压完美实现

改进后的代码

import java.io.*;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

/**
 * date:2019/7/26
 * writed by yangtingting
 */

public class zipUncompress {
    /**
     * zip文件解压
     * @param inputFile  待解压文件夹/文件
     * @param destDirPath  解压路径
     */
    public static void zipUncompress(String inputFile,String destDirPath) throws Exception {
        File srcFile = new File(inputFile);//获取当前压缩文件
        // 判断源文件是否存在
        if (!srcFile.exists()) {
            throw new Exception(srcFile.getPath() + "所指文件不存在");
        }
        ZipFile zipFile = new ZipFile(srcFile);//创建压缩文件对象
        //开始解压
        Enumeration entries = zipFile.entries();
        while (entries.hasMoreElements()) {
            ZipEntry entry = (ZipEntry) entries.nextElement();
            // 如果是文件夹,就创建个文件夹
            if (entry.isDirectory()) {
                String dirPath = destDirPath + "/" + entry.getName();
                srcFile.mkdirs();
            } else {
                // 如果是文件,就先创建一个文件,然后用io流把内容copy过去
                File targetFile = new File(destDirPath + "/" + entry.getName());
                // 保证这个文件的父文件夹必须要存在
                if (!targetFile.getParentFile().exists()) {
                    targetFile.getParentFile().mkdirs();
                }
                targetFile.createNewFile();
                // 将压缩文件内容写入到这个文件中
                InputStream is = zipFile.getInputStream(entry);
                FileOutputStream fos = new FileOutputStream(targetFile);
                int len;
                byte[] buf = new byte[1024];
                while ((len = is.read(buf)) != -1) {
                    fos.write(buf, 0, len);
                }
                // 关流顺序,先打开的后关闭
                fos.close();
                is.close();
            }
        }
    }
    public static void main(String[] args) {
        try {
            zipUncompress("D:\\ytt.zip","D:\\ytt的解压文件");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

4 FileZip.class 实现.zip压缩与解压

完整代码:

import java.io.*;
import java.util.zip.*;
import java.util.zip.ZipEntry;

/**
 * date: 2019/07/26
 * writed by yangtingting
 */
public class FileZip {
    /**
     * zip文件压缩
     * @param inputFile 待压缩文件夹/文件名
     * @param outputFile 生成的压缩包名字
     */

    public static void ZipCompress(String inputFile, String outputFile) throws Exception {
        //创建zip输出流
        ZipOutputStream out = new ZipOutputStream(new FileOutputStream(outputFile));
        //创建缓冲输出流
        BufferedOutputStream bos = new BufferedOutputStream(out);
        File input = new File(inputFile);
        compress(out, bos, input,null);
        bos.close();
        out.close();
    }
    /**
     * @param name 压缩文件名,可以写为null保持默认
     */
    //递归压缩
    public static void compress(ZipOutputStream out, BufferedOutputStream bos, File input, String name) throws IOException {
        if (name == null) {
            name = input.getName();
        }
        //如果路径为目录(文件夹)
        if (input.isDirectory()) {
            //取出文件夹中的文件(或子文件夹)
            File[] flist = input.listFiles();

            if (flist.length == 0)//如果文件夹为空,则只需在目的地zip文件中写入一个目录进入
            {
                out.putNextEntry(new ZipEntry(name + "/"));
            } else//如果文件夹不为空,则递归调用compress,文件夹中的每一个文件(或文件夹)进行压缩
            {
                for (int i = 0; i < flist.length; i++) {
                    compress(out, bos, flist[i], name + "/" + flist[i].getName());
                }
            }
        } else//如果不是目录(文件夹),即为文件,则先写入目录进入点,之后将文件写入zip文件中
        {
            out.putNextEntry(new ZipEntry(name));
            FileInputStream fos = new FileInputStream(input);
            BufferedInputStream bis = new BufferedInputStream(fos);
            int len=-1;
            //将源文件写入到zip文件中
            byte[] buf = new byte[1024];
            while ((len = bis.read(buf)) != -1) {
                bos.write(buf,0,len);
            }
            bis.close();
            fos.close();
        }
    }

    /**
     * zip解压
     * @param inputFile 待解压文件名
     * @param destDirPath  解压路径
     */

    public static void ZipUncompress(String inputFile,String destDirPath) throws Exception {
        File srcFile = new File(inputFile);//获取当前压缩文件
        // 判断源文件是否存在
        if (!srcFile.exists()) {
            throw new Exception(srcFile.getPath() + "所指文件不存在");
        }
        //开始解压
        //构建解压输入流
        ZipInputStream zIn = new ZipInputStream(new FileInputStream(srcFile));
        ZipEntry entry = null;
        File file = null;
        while ((entry = zIn.getNextEntry()) != null) {
            if (!entry.isDirectory()) {
                file = new File(destDirPath, entry.getName());
                if (!file.exists()) {
                    new File(file.getParent()).mkdirs();//创建此文件的上级目录
                }
                OutputStream out = new FileOutputStream(file);
                BufferedOutputStream bos = new BufferedOutputStream(out);
                int len = -1;
                byte[] buf = new byte[1024];
                while ((len = zIn.read(buf)) != -1) {
                    bos.write(buf, 0, len);
                }
                // 关流顺序,先打开的后关闭
                bos.close();
                out.close();
            }
        }
    }


    public static void main(String[] args) {
        try {
            ZipCompress("D:\\Test", "D:\\TestbyYTT.zip");
            ZipUncompress("D:\\ytt.zip","D:\\ytt的解压文件");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

你可能感兴趣的:(Java学习)