错误展示:

错误代码:


import java.io.*;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;/*** @author 何* @date 2019-08-13 15:06*/
public class MyZipUtil {public static void main(String[] args) throws IOException {testZip("D:\\zip\\", "D:\\zip\\test.zip", 0);}/**** @param srcFilesAbsoluteParentPath 需要被压缩的文件的绝对父路径 例:   D:\\zip   压缩这个目录下所有的文件* @param targetZipFileAbsolutePath  需要压缩到指定的位置的绝对路径(含文件名) 例:  D:\\zip\\test.zip  压缩文件就放在这个位置* @throws IOException*/public static void testZip(String srcFilesAbsoluteParentPath, String targetZipFileAbsolutePath, int depth)throws IOException{//列出此目录所有文件,遍历操作File parentPath = new File(srcFilesAbsoluteParentPath);File[] files = parentPath.listFiles();//创建一个Zip文件输出流ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(targetZipFileAbsolutePath));for (int i = 0; i < files.length; i++) {File currentFile = files[i];//如果是目录则递归调用此方法if(currentFile.isDirectory()){testZip(currentFile.getAbsolutePath()+"\\", targetZipFileAbsolutePath, depth+1);continue;}/*根据目录深度,拼接zip文件里面的各个深度的文件的层次结构比如 在外面相对路径是 dir1/dir2/test.txt ,这个时候的文件名test.txt是不可以直接拿来作为entry的名字的,应该根据深度,获取他们的父目录的名称 拼接为  dir1/dir2/test.txt这样子才能保证层次结构不乱*/StringBuilder entryName = new StringBuilder(files[i].getName());File tempFile = files[i];for (int j = 0; j < depth; j++) {tempFile = tempFile.getParentFile();entryName.insert(0, tempFile.getName() + "\\");}zos.putNextEntry(new ZipEntry(entryName.toString()));//根据此文件创建输入流,用于等下文件的复制FileInputStream fis = new FileInputStream(currentFile.getAbsolutePath());//文件复制byte[] bytes = new byte[1024];int readedInt = 0;while( (readedInt=fis.read(bytes, 0, bytes.length))!=-1){zos.write(bytes, 0, readedInt);}fis.close();  //流要关闭}zos.finish();zos.close();}}

执行前文件结构截图

执行后的压缩文件内部截图

发现压缩文件的时候,并没有把更深层次的文件压缩进去。

错误原因:

如图可以看到,每次递归调用自身的时候,输出流的引用都指向了的更新的对象。即“对象”被“重置”了。

大概文件夹目录的文件虽然被正常压缩进去了,可是被外围的递归方法中产生的新的输出流给 覆盖 了。所以这就是为什么没报错,却也没有将子目录里面的文件压缩进去的原因。(本来压缩了,由于递归方法内我将输出流重置的原因,他被冲洗掉了)

警惕:

慎用递归,在循环调用自身的时候,一定要想清楚,哪些是在变的,哪些是不在变的。像我这个例子就是没有注意到 这个压缩文件应该自始至终都是“一个输出流”才对

贴上改正后自己写的Zip格式非加密 压缩与解压缩的工具类

ZipUtils.java

package com.zmedu.sdk.utils;import org.junit.Test;import java.io.*;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;/*** @author 何* @date 2019-08-13 15:06*/
public class MyZipUtil {public static void main(String[] args) throws IOException {//        testZip("D:\\zip\\", "D:\\zip\\test.zip", 0);testUnzip("D:\\students\\students.zip", "D:\\students\\");}/**** @param srcFilesAbsoluteParentPath 需要被压缩的文件的绝对父路径 例:   D:\\zip   压缩这个目录下所有的文件* @param targetZipFileAbsolutePath  需要压缩到指定的位置的绝对路径(含文件名) 例:  D:\\zip\\test.zip  压缩文件就放在这个位置* @throws IOException*/public static void testZip(String srcFilesAbsoluteParentPath, String targetZipFileAbsolutePath, int depth)throws IOException{//列出此目录所有文件,遍历操作File parentPath = new File(srcFilesAbsoluteParentPath);File[] files = parentPath.listFiles();//创建一个Zip文件输出流ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(targetZipFileAbsolutePath));for (int i = 0; i < files.length; i++) {File currentFile = files[i];//如果是目录则递归调用此方法if(currentFile.isDirectory()){testZip(currentFile.getAbsolutePath()+"\\", targetZipFileAbsolutePath, depth+1);continue;}/*根据目录深度,拼接zip文件里面的各个深度的文件的层次结构比如 在外面相对路径是 dir1/dir2/test.txt ,这个时候的文件名test.txt是不可以直接拿来作为entry的名字的,应该根据深度,获取他们的父目录的名称 拼接为  dir1/dir2/test.txt这样子才能保证层次结构不乱*/StringBuilder entryName = new StringBuilder(files[i].getName());File tempFile = files[i];for (int j = 0; j < depth; j++) {tempFile = tempFile.getParentFile();entryName.insert(0, tempFile.getName() + "\\");}zos.putNextEntry(new ZipEntry(entryName.toString()));//根据此文件创建输入流,用于等下文件的复制FileInputStream fis = new FileInputStream(currentFile.getAbsolutePath());//文件复制byte[] bytes = new byte[1024];int readedInt = 0;while( (readedInt=fis.read(bytes, 0, bytes.length))!=-1){zos.write(bytes, 0, readedInt);}fis.close();  //流要关闭}zos.finish();zos.close();}/*** 解压Zip格式的非加密压缩文件*  提示:可以解压子目录的文件到对应的结构下,即这个压缩文件的子目录下还有孙子目录,也能一并解压*  缺点:不能解压里面的zip文件*  思路:可将每个 .zip 后缀的文件作为一个ZipFile的实例对象,调用.size()方法,抛出*                  java.util.zip.ZipException: error in opening zip file*       上面异常的则表示这个是不能打开的压缩文件,或者压根就不是压缩文件* @param zipFileAbsolutePath 压缩文件的绝对路径* @param destinationAbusolutePath 解压目的地的绝对路径* @throws IOException*/public static void testUnzip(String zipFileAbsolutePath, String destinationAbusolutePath) throws IOException {//根据压缩文件创建一个文件输入流,再创建一个Zip的专门的输入流FileInputStream fis = new FileInputStream(zipFileAbsolutePath); //"D:\\test\\test.zip"ZipInputStream zis = new ZipInputStream(fis);//可以当成压缩文件里面的条目ZipEntry zipEntry = null;//遍历所有条目 ,本质上就是把他们全部给复制一份出来while((zipEntry = zis.getNextEntry())!=null){System.out.println("当前文件: " + zipEntry.getName() + ", 大小: " + zipEntry.getSize());
//            ZipFile zipFile = new ZipFile("D:\\unzip\\FacePictures\\xxx\\Faces List.txt");
//            System.out.println(zipFile.size());//如果是目录则建个目录,不用自己去深度遍历,zis.getNextEntry会自动获取本压缩文件下的所有文件if(zipEntry.isDirectory()){File file = new File(destinationAbusolutePath+zipEntry.getName());file.mkdirs();continue;}//创建一个输出流,文件输出流或者字节数组输出流都行,二选一即可File beCreateedFile = new File(destinationAbusolutePath+zipEntry.getName());System.out.println("beCreateedFile: " + beCreateedFile);if (!(beCreateedFile.getParentFile().exists())) {beCreateedFile.getParentFile().mkdirs();}FileOutputStream fos = new FileOutputStream(beCreateedFile); //"D:\\test\\"ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();/*  第一种: 使用字节数组输出流的方式   *//*****************************************/byte[] bytes = new byte[1024];  //长度随意int readedInt = 0;while((readedInt = zis.read(bytes, 0, bytes.length)) != -1){fos.write(bytes, 0, readedInt);byteArrayOutputStream.write(bytes, 0, readedInt);}fos.close();/*****************************************//*  第二种:  使用字节数组输出流的方式   *//*****************************************/
//            byte[] imgBytes = byteArrayOutputStream.toByteArray();
//            fos = new FileOutputStream(destinationAbusolutePath+zipEntry.getName());
//            fos.write(imgBytes);
//            fos.close();/*****************************************/zis.closeEntry(); // 文档说要关闭,可是不关闭也可以,还是关闭把}//流要记得关闭!zis.close();fis.close();}
}

递归的使用不当 导致 压缩文件不能压缩二级目录相关推荐

  1. pdf压缩文件怎么压缩最小

    pdf压缩文件怎么压缩最小?pdf文件我们在职场中接触的是很多的,但有时候文件太大导致我们在文件打开和传输的时候速度很慢.为了解决这个问题.我们会将pdf文件进行压缩,pdf压缩文件怎么压缩最小呢? ...

  2. 电脑上怎么做pdf文件_PDF压缩文件怎么压缩最小?请收好这些PDF压缩方法

    刚才想把手头上的一份PDF文件发给同事,直接拖进窗口就显示文件太大,超出了大小限制.还好我平时经常要处理PDF文件,这种情况下将PDF文件压缩一下就可以了.PDF文件怎么进行压缩呢?下面我就把常用的P ...

  3. linux 解压tar.jz,linux系统压缩文件和解压缩命令

    linux系统压缩文件和解压缩命令 tar命令 解包:tar zxvf FileName.tar 打包:tar czvf FileName.tar DirName gz命令 解压1:gunzip Fi ...

  4. ppt压缩文件怎么压缩最小,ppt无损压缩

    ppt压缩文件怎么压缩最小? 在工作中,我们经常需要制作PPT文件进行汇报和分享,但有时候这些文件太大了,会影响下载和分享的速度,从而影响到工作效率.为了解决这个问题,我们可以对PPT文件进行压缩,从 ...

  5. pdf压缩文件怎么压缩最小,pdf大小超过上传大小不能上传怎么压缩?

    pdf压缩文件怎么压缩最小?pdf是日常办公中比较常见的一种文件格式,但是有时候pdf文件的容量会比较大,上传到某些平台会有限制,那么我们就需要压缩pdf文件,但是有时候压缩处理会模糊,今天我给大家介 ...

  6. ppt压缩文件怎么压缩最小?

    ppt压缩文件怎么压缩最小?ppt的全称是PowerPoint ,又叫幻灯片,是目前使用比较广泛的文件格式之一,会议报告文件或者自己的工作汇报等都是采用这种文件格式.ppt采用图文并茂的方式进行呈现, ...

  7. 电脑rar文件打开方式_怎么压缩文件,如何压缩文件?压缩软件哪个好?

    超过10万人正在关注 赶快来关注吧,这里有你想找的热点资讯,这里有你想要的各种资料,还有海量的资源,还在等什么.快来关注,大佬带你开车. 在用电脑储存或者下载东西的时候,我们经常会遇到压缩的文件,或者 ...

  8. PDF压缩文件怎么压缩?两分钟让你学会三种方法

    我们在传输PDF文件的时候,偶尔会因为文件过大,导致传输速度过长,甚至有时会提示,超出可传输的文件大小.这种时候就需要我们减小PDF文件的体积了,那有什么办法可以既保证文件内容质量,又可以减小文件体积 ...

  9. python压缩文件不带根路径_python 压缩文件(解决压缩路径问题)

    #压缩文件 def Zip_files(): datapath = filepath # 证据路径 file_newname = datapath + '.zip' # 压缩文件的名字 log.deb ...

最新文章

  1. 处理您的请求时发生错误(Web Dynpro ABAP)
  2. ubuntu apache php mysql phpmyadmin_Ubuntu下Apache+PHP+MySQL+phpMyAdmin的快速安装步骤
  3. php安装编译时 configure: error: Cannot find OpenSSL's evp.h
  4. c++ winpcap开发(4)
  5. 解决VS2017引用报错问题
  6. Android java传递int类型数组给C
  7. 刷新按钮_不能忍:用户求微软为Win10 Wi-Fi窗口添加刷新按钮
  8. Firefox的缓存问题
  9. Ubuntu14 添加程序启动
  10. ROS Learning-008 beginner_Tutorials ROS话题
  11. Framework4.5,vs下系统自动生成的C++ win32应用程序的详细解释
  12. python谐音梗_谐音梗生成器
  13. 论基于构件的软件开发
  14. mysql错误:Table XXX is marked as crashed and should be repaire
  15. 想要成为大牛应该做到以下几点
  16. mat1 and mat2 shapes cannot be multiplied (3584x7 and 512x4096)
  17. 轻薄旗舰投影两大阵营大眼橙X7D Pro和极米Z7X,谁才是真正的高性价比之选?
  18. UEFI启动模式下, 双硬盘安装UBuntu16.04与Win10双系统
  19. 三种方法求最大公约数(C语言版)
  20. 电脑插了两根内存条只读出来一根,另一条是为硬件保留的内存空间

热门文章

  1. iPhone 14 Pro系列传出好消息,有望实现8GB内存自由
  2. 高通第一财季营收107亿美元 净利润超过30亿美元
  3. “真还传”即将完结?锤子科技撤回全部破产申请 罗永浩称年后回归科技界
  4. 何小鹏:雷军造车是我“怂恿的” 我一直建议小米要造车
  5. 知乎回应月饼问题:忽略了麦芽糖或致部分人不耐受,召回所有月饼
  6. 妙啊,小米11保护壳先小米11一步上市了...
  7. 北京一Model 3失控冲向公交站台,特斯拉调查后回应......
  8. 前华为、魅族CMO加盟小米,雷军这样评价
  9. iPad有望带来全面鼠标支持 大幅提升游戏体验
  10. 16999元!华为Mate X 5G折叠屏手机正式发布:不愧是限量款