android 解压相关问题,解压文件失败的情况

昨日夜间,被公司的商务同事电话催醒。。。说了一个让我头痛的问题:
现场的app不好使了,下载照片的时候,一个手机下载照片然后解压可以正常解压,但是只要多个手机同时下载,照片就无法解压(What?程序已经写好的,出现的问题怎么会是毫无关联的设备引发…头痛)
在洗了把脸清醒之后,仔细想了想问题,无法解压肯定是与设备无关的,只能是在下载过程中和下载后的文件出现了异常,所以无法解压!
我先试了下使用浏览器下载,发现问题是在下载完成后发生的,下载下来的zip包会有无法解压、zip包已损坏、文件已损坏的情况出现,至此,就可以肯定了,问题出现在后台!本来想着发生源找到了,就直接睡觉,想了想,还是在联系自己的代码好好看一看吧,能优化还是尽量优化的好,毕竟不想再被半夜弄起来了(T-T…)
在查看代码后,确实发现了一些有意思的事情,目前尝试了4种zip包解压情况:
1、zip文件正常
2、zip文件无法解压(即下载的文件大小极小)
3、zip文件损坏,无法解压
4、zip文件中数据损坏,无法解压
第一种情况,很简单,直接使用原有的ZipFile就可以正常解压。
第二种和第三种情况,也可以使用ZipFile来判断,直接throw异常就可以了
而这第四种,就是比较特殊的了,为什么说是特殊呢,因为zip文件的数据损坏,但是zip文件却是可以正常解压的,只不过就是解压不出来数据而已(代码逻辑非设备类解压逻辑),但是不会throw异常,而是一直在解析当前zip文件,然后就会出现zip文件解压时间很长才会进行下一步的操作!
那么问题就来了,既然解析不出来文件,为什么会解压这么长的时间才返回失败呢?
在经历了一系列的debug和源码查询后,终于发现了这个问题:
在ZipFile.class的源文件中,有这么一个方法在这里插入图片描述
在勾选中的红色圆圈里,this.archive.read()与ZipOutputStream.EOCD_SIG进行判断,但是debug发现this.archive.read()竟然有241010256L,猜想会不会是这里耗时太多,导致解压时间过长(看到这里正在查找ZipOutputStream.EOCD_SIG和this.archive.read()分别代表什么意思,如果有知道的兄弟姐妹们,评论区指点一下,谢谢),看到这里,发现当前使用的zipFile方法解压还是存在问题,所以尝试了下另一种方法进行解压:FileInputStream
FileInputStream方式是先判断流,然后在获取文件的数据,这样就直接知晓了文件是否已损坏,不用再耗时了!

BufferedOutputStream dest = null;
        FileInputStream fis =new FileInputStream(archive);
        ZipInputStream zis =new ZipInputStream(new BufferedInputStream(fis));
//            ZipInputStream zis = new ZipInputStream();
        ZipEntry entry;
        if(zis.getNextEntry() == null){
            throw new Exception("解压文件异常");
        }

但是,使用FileInputStream解压还存在一个弊端,那就是ZipFile较ZipInputStream相比,耗时仍有15%-22%的减少,也就是说正常文件时候,解压的效率还是ZipFile快的,那么,可不可以将两种方法合并一下呢?

BufferedOutputStream dest = null;
        FileInputStream fis =new FileInputStream("文件路径");
        ZipInputStream zis =new ZipInputStream(new BufferedInputStream(fis));
//            ZipInputStream zis = new ZipInputStream();
        ZipEntry entry;
        if(zis.getNextEntry() == null){
            throw new Exception("解压文件异常");
        }else {
            ZipFile zf = new ZipFile(archive, "UTF-8");
            Enumeration e = zf.getEntries();
            while (e.hasMoreElements()) {
                ZipEntry ze2 = (ZipEntry) e.nextElement();
                String entryName = ze2.getName();
                //String pic_url = "";
//            if (entryName.indexOf("/") > 0 && entryName.indexOf(".") > 0) {
//                // pic_url = entryName.substring(entryName.indexOf("/") + 1, entryName.lastIndexOf("."));
//                if (StudentPicUrldbHelper.getInstance().selectPicBySchIDType(mid, entryName, logintype)) {
//                    StudentPicUrlDomain mStudentPicUrlDomain = StudentPicUrldbHelper.getInstance().getmStudentPicUrlDomain();
//                    mStudentPicUrlDomain.setLogin_type(logintype);
//                    mStudentPicUrlDomain.setPic_name(name);
//                    mStudentPicUrlDomain.setPic_url(entryName);
//                    mStudentPicUrlDomain.setSessionId(mid);
//                    mStudentPicUrlDomain.setSch_name(name);
//                    StudentPicUrldbHelper.getInstance().updateStudentPicUrlDomain(mStudentPicUrlDomain);
//                } else {
//                    StudentPicUrlDomain mStudentPicUrlDomain = new StudentPicUrlDomain();
//                    mStudentPicUrlDomain.setLogin_type(logintype);
//                    mStudentPicUrlDomain.setPic_name(name);
//                    mStudentPicUrlDomain.setPic_url(entryName);
//                    mStudentPicUrlDomain.setSessionId(mid);
//                    mStudentPicUrlDomain.setSch_name(name);
//                    StudentPicUrldbHelper.getInstance().insertStudentPicUrlDomain(mStudentPicUrlDomain);
//                }
//            }
                String path = "解压的目的地文件夹路径" + "/" + entryName;
                if (ze2.isDirectory()) {
                    System.out.println("正在创建解压目录 - " + entryName);
                    File decompressDirFile = new File(path);
                    if (!decompressDirFile.exists()) {
                        decompressDirFile.mkdirs();
                    }
                } else {
                    System.out.println("正在创建解压文件 - " + entryName);
                    String fileDir = path.substring(0, path.lastIndexOf("/"));
                    File fileDirFile = new File(fileDir);
                    if (!fileDirFile.exists()) {
                        fileDirFile.mkdirs();
                    }
                    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(decompressDir + "/" + entryName));
                    bi = new BufferedInputStream(zf.getInputStream(ze2));
                    byte[] readContent = new byte[1024];
                    int readCount = bi.read(readContent);
                    while (readCount != -1) {
                        bos.write(readContent, 0, readCount);
                        readCount = bi.read(readContent);
                    }
                    bos.close();
                }
            }
            zf.close();
        }

如上,先使用FileInputStream判断文件是否完好,然后使用Zipfile解压!

以上,为临时思路记录,语言逻辑有些混乱,如有不清楚的地方请评论区留言,共同探讨!!!
如有不对,请评论区指正!虚心学习!谢谢!
路过的兄弟姐妹们,如有清楚相关问题的,也希望在评论区留下您独到的见解!!!

  • 5
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Kstar_Ming_闫

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值