美文网首页Java-多线程
Java 多线程解压文件

Java 多线程解压文件

作者: 贼噶人 | 来源:发表于2020-12-07 20:55 被阅读0次
    private static AtomicBoolean isMThreadUnZip = new AtomicBoolean(true);
        private static ListeningExecutorService unzipExecutor = MoreExecutors
                .listeningDecorator(new ThreadPoolExecutor(2,
                        Math.max(Runtime.getRuntime().availableProcessors() - 2, 2), 15,
                        TimeUnit.SECONDS,
                        new LinkedBlockingQueue<Runnable>()));
    
        public static abstract class UnzipListener {
            public abstract void success();
    
            public void onUnzip(float progress) {
            }
    
            public void fail(String message) {
            }
        }
    
        static class UnZipCallable implements Callable<Boolean> {
            private InputStream zipInputStream;
            private File target;
            private BufferedSink sink;
            private BufferedSource source;
    
            public UnZipCallable(final InputStream zipInputStream, final File target) {
                this.zipInputStream = zipInputStream;
                this.target = target;
            }
    
            @Override
            public Boolean call() throws Exception {
                try {
                    sink = Okio.buffer(okio.Okio.sink(target));
                    source = Okio.buffer(Okio.source(zipInputStream));
                    source.readAll(sink);
                    sink.flush();
                    return true;
                } finally {
                    close(source);
                    close(sink);
                }
            }
        }
    
    
        /**
         * 多线程解压文件
         * @param file
         * @param targetDir
         * @param clear
         * @param listener
         */
        public static void unzipByMThread(File file, File targetDir, boolean clear,
                                 final UnzipListener listener) {
            if (clear) {
                clearDir(targetDir);
                //以前是Libgdx课程,现在是Unity的删除老的Libgdx课程下载
                if (!targetDir.getAbsolutePath().contains(File.separator + "common")
                        && targetDir.getAbsolutePath().contains(File.separator + "unity" + File.separator)) {
                    clearDir(new File(targetDir.getAbsolutePath().replace("unity"
                            + File.separator, "")));
                }
            }
            if (!targetDir.exists()) {
                if (!targetDir.mkdirs()) {
                    if (null != listener) {
                        listener.fail("创建目录失败");
                    }
                    return;
                }
            }
            final String targetPath = targetDir.getAbsolutePath() + File.separator;
            ZipFile zip = null;
            try {
                zip = new ZipFile(file);
                final Enumeration<? extends ZipEntry> entries = zip.entries();
                final int size = zip.size();
                final AtomicInteger current = new AtomicInteger(0);
                final AtomicBoolean isException = new AtomicBoolean(false);
                final CountDownLatch countDownLatch = new CountDownLatch(size);
                final ZipFile hZip = zip;
                try {
                    while (!isException.get() && entries.hasMoreElements()) {
                        final ZipEntry entry = entries.nextElement();
                        final File target = new File(targetPath + entry.getName());
                        if (entry.isDirectory()) {
                            if (!target.exists()) {
                                target.mkdirs();
                            }
                            current.incrementAndGet();
                            if (null != listener) {
                                listener.onUnzip(1f * current.get() / size);
                            }
                            countDownLatch.countDown();
                            continue;
                        } else if (!target.exists()) {
                            if (!target.getParentFile().exists()) {
                                target.getParentFile().mkdirs();
                            }
                        }
                        Futures.addCallback(unzipExecutor.submit(new UnZipCallable(hZip.getInputStream(entry)
                                , target)), new FutureCallback<Boolean>() {
                            @Override
                            public void onSuccess(final Boolean result) {
                                current.incrementAndGet();
                                if (null != listener) {
                                    listener.onUnzip(1f * current.get() / size);
                                }
                                countDownLatch.countDown();
                            }
                            @Override
                            public void onFailure(Throwable throwable) {
                                isException.set(true);
                                isMThreadUnZip.set(false);
                                while (countDownLatch.getCount() > 0) {
                                    countDownLatch.countDown();
                                }
                            }
                        });
                    }
                } catch (final Exception e) {
                    isException.set(true);
                    isMThreadUnZip.set(false);
                    while (countDownLatch.getCount() > 0) {
                        countDownLatch.countDown();
                    }
                }
                countDownLatch.await(5, TimeUnit.MINUTES);
                if (isException.get()) {
                    throw new Exception("Unzip Exception");
                }
                if (null != listener) {
                    listener.onUnzip(1f);
                    listener.success();
                }
            }
            catch (Exception e)
            {
                try {
                    if (e instanceof ZipException
                            && (e.getMessage().contains("File too short to")
                            || 0 == file.length())) {
                        ClazzObservable.getInstance().notifyObservers();
                    }
                } catch (Exception ex) {
    
                }
                clearDir(targetDir);
                if (null != listener)
                {
                    listener.fail("解压失败:" + e.getClass().getSimpleName());
                }
                try
                {
                    Platform.get().getAppManager().putUmAgent(Gdx.app, new Exception(targetDir + "#"
                            + e.getMessage(), e));
                }
                catch (Exception ex)
                {
    
                }
            }
            finally
            {
                if (null != zip && zip instanceof Closeable)
                {
                    close(zip);
                }
            }
        }
    

    相关文章

      网友评论

        本文标题:Java 多线程解压文件

        本文链接:https://www.haomeiwen.com/subject/svtxgktx.html