android 关于zip4j的一些天坑

1.最近的项目中有个需求,就是从oos上下载压缩包并且解压,对swf解密的需求。

2.解压过程中,要显示解压进度。解压成功后对swf文件解密。

3.关于显示解压进度的天坑:网上十片有八篇的方法:

/**
     * @param zipFile     需要解压的文件
     * @param filePath    解压后的文件目录
     * @param isDeleteZip 是否删除解压包
     * @throws ZipException
     */
    private void unZipFileWithProgress(File zipFile, String filePath, boolean isDeleteZip) throws ZipException {
        String usbOrTfPath = zipFile.getAbsolutePath();
        ZipFile zFile = new ZipFile(zipFile);
        zFile.setFileNameCharset("GBK");
        if (!zFile.isValidZipFile()) {
            if (zipFileImp != null) {
                flag_unZip = false;
                zipFileImp.copyAndUnPackFailed("文件不合法或不存在" + zipFile.getAbsolutePath());
            }
            Log.e("======", "文件不合法或不存在" + zipFile.getAbsolutePath());
            return;
        }
        File destDir = new File(filePath); // ��ѹĿ¼
        if (destDir.isDirectory() && !destDir.exists()) {
            destDir.mkdir();
        }
        if (zFile.isEncrypted()) {
            // zFile.setPassword(password); // 设置解压密码
        }


        // if (totalWork != 0) {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    flag_unZip = true;
                    ProgressMonitor progressMonitor = zFile.getProgressMonitor();
                    int precentDone = 1;
                    boolean isFileeixst = false;
                    while (flag_unZip) {
                        Log.i("TTFFGG", "RRRR");
                        File nomorlFile = new File(usbOrTfPath);
                        if (nomorlFile != null && nomorlFile.exists()) {
                            isFileeixst = true;

                        } else {
                            isFileeixst = false;
                            if (zipFileImp != null) {
                                flag_unZip = false;
                                zipFileImp.usbHasTakeOut("发现U盘拔出");
                            }
                        }

                        // 每隔50ms,发送一个解压进度出去
                        // if (progressMonitor.getTotalWork() > 0) {
                        precentDone = progressMonitor.getPercentDone();
                        //
                        if (zipFileImp != null) {
                            if (precentDone != 0 && lastProgress == 0) {
                                //开始
                                Logger.i("解压SSS1::" + progressMonitor.getTotalWork() + ":::" + progressMonitor.getWorkCompleted());
                                zipFileImp.copyAndUnPackProgress(precentDone * 80 / 100);
                                lastProgress = precentDone;
                            } else if (precentDone != 0 && lastProgress != 0) {
                                Logger.i("解压SSS2::" + progressMonitor.getTotalWork() + ":::" + progressMonitor.getWorkCompleted());
                                zipFileImp.copyAndUnPackProgress(precentDone * 80 / 100);
                                lastProgress = precentDone;
                            } else if (precentDone == 0 && lastProgress != 0) {
                                Logger.i("解压SSS3::" + progressMonitor.getTotalWork() + ":::" + progressMonitor.getWorkCompleted());
                                //if (progressMonitor.getTotalWork() != 0 && progressMonitor.getWorkCompleted() != 0) {
                                if (progressMonitor.getTotalWork() == progressMonitor.getWorkCompleted()) {
                                    // flag_unZip = false;

                                    if (zipFileImp != null) {
                                        Thread.sleep(2500);
                                        File nomorlFile2 = new File(usbOrTfPath);
                                        if (nomorlFile2 != null && nomorlFile2.exists() && isFileeixst) {
                                            Log.i("copy materials==", "解压成功" + zipFile.getAbsolutePath());
                                            flag_unZip = false;
                                            zipFileImp.copyAndUnPackSuccess();
                                        } else {
                                            if (zipFileImp != null) {
                                                flag_unZip = false;
                                                zipFileImp.usbHasTakeOut("发现U盘拔出");
                                            }
                                            Log.i("copy materials==", "发现U盘拔出" + usbOrTfPath);
                                        }
                                    }
                                }
                            }
                        }
                    }
                } catch (Exception e) {
                    Log.i("copy materials==", "解压失败" + e.getMessage());
                    if (zipFileImp != null) {
                        flag_unZip = false;
                        zipFileImp.copyAndUnPackFailed(e.getMessage().toString());
                    }
                } finally {
                    if (isDeleteZip) {
                        flag_unZip = false;
                        zipFile.delete();//将原压缩文件删除
                    }
                }
            }
        });
        thread.start();
        zFile.setRunInThread(true); //true 在子线程中进行解压 , false主线程中解压
        zFile.extractAll(filePath); //将压缩文件解压到filePath中...
    }

1.这个方法有个很大的问题就是,进度不完整,解压成功的判定有很大的漏洞(当解压文件在U盘,解压过程中拔出U盘竟然会走解压成功的判定!!!)

progressMonitor.getTotalWork() == progressMonitor.getWorkCompleted()

2.尚且没有好的解决办法

3.只能采取第二种解压方法但也有局限(必须是多个文件的压缩包)

 /**
     * 课件整包,解压方法
     *
     * @param archive
     * @param unicode
     * @param decompressDir
     * @param uiHandler
     * @param allCount
     */
    public static void unZipFileByZip4j(final String archive, final String unicode, final String decompressDir, final Handler uiHandler, final int allCount, UnZipCallBack unZipCallBack) {
        stopUnzip = false;
        try {
            int currentProcess = 0;
            int oldProcess = 0;
            long startTime = System.currentTimeMillis();
            ZipFile zipFile2 = new ZipFile(archive);
            FileHeader fileHeader = null;
            //设置编码格式
            zipFile2.setFileNameCharset(unicode);
            if (!zipFile2.isValidZipFile()) {
                Log.e("======", "文件不合法或不存在");
                return;
            }
            List fileHeaderList = zipFile2.getFileHeaders();
            for (int i = 0; i < fileHeaderList.size(); i++) {
                if(!stopUnzip){
                    fileHeader = fileHeaderList.get(i);
                    zipFile2.extractFile(fileHeader, decompressDir);
                    ProgressMonitor progressMonitor = zipFile2.getProgressMonitor();
                    currentProcess = (i + 1) * allCount / fileHeaderList.size();
                    if (currentProcess != oldProcess && currentProcess < 101) {
                        oldProcess = currentProcess;
                        Message message = new Message();
                        Bundle bundle = new Bundle();
                        message.what = Constants.unzipCourse;
                        bundle.putInt("currentTotal", currentProcess);
                        message.obj = bundle;
                        uiHandler.sendMessage(message);
                    }
                }
            }
            if(!stopUnzip){
                Log.e("======", "解压成功!");
                unZipCallBack.onSuccess(archive);
                long endTime = System.currentTimeMillis();
                Log.e("======", "耗时:" + (endTime - startTime) + "ms");
            }
        } catch (Exception e) {
            if(!stopUnzip){
                Log.e("======", e.toString());
                unZipCallBack.onFail(e.toString(), archive);
            }
        }
    }

 

你可能感兴趣的:(Android)