Java中实现zip的压缩与解压缩
1 基本概念
ZipOutputStream 实现文件的压缩
ZipOutputStream (OutputStream out) 创建新的zip输出流
void putNextEntry(ZipEntry e) 开始写入新的zip文件条目并将流定位到条目数据的开始处
条目指的是一个文件夹下的多个文件。
ZipEntry(String name) 使用指定名称创建新的zip条目
ZipIutputStream实现文件的解压
ZipIutputStream (IutputStream out) 创建新的zip输入流
ZipEntry getNextEntry()读取下一个zip条目并将流定位到该条目数据的开始处
2 zip压缩
2.1 zip压缩代码实现
程序完整代码
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | 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依赖:
| 1 2 3 4 5 |     <dependency>         <groupId>org.apache.commons</groupId>         <artifactId>commons-compress</artifactId>         <version>1.12</version>     </dependency> | 
运行程序:

3.程序解读:
ZipEntry(String name) 只能实现一个固定条目的压缩,也就是你压缩什么就得写仔细它的路径,多个子文件压缩写法如下:
| 1 2 3 4 5 6 7 8 | 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。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | 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 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | 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();         }     } } | 
以上代码运行时会抛出异常!!!!!!!!!
做出相应更改:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | 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解压完美实现
改进后的代码:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | 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压缩与解压
完整代码:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | 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();          }     } } | 
转自:https://blog.csdn.net/qq_34474324/article/details/97369763