多线程 zip4j

Multi Thread zip4j

zip4j 是一个很棒的库。但是我 运行 在使用线程的 class 中使用它时遇到了问题。 zip4j 方法是从实现线程的 class 调用的,有时(并非总是)它使文件未压缩,有时还有扩展名为 *.zip345 的 leftofer 文件。还有进程 returns net.lingala.zip4j.exception.ZipException: 无法重命名修改后的 zip 文件。

zip4jProcess 方法是从 class public 方法中调用的。 Class 名字是:SZipInterface.class

SZipInterface.class 在线程 class ex: ThreadObj.class 中初始化并按线程实例化。没有使用静态方法。

问题的原因是什么?你如何解决它? zip4j 线程安全吗?

方法:

    private int zip4jProcess() {
    int status = 0;
    if (null != getInFiles() && getInFiles().length > 0) {
        for (String file : getInFiles()) {
            File sourceFile = new File(file);
            ZipFile zipFile = null;
            ZipParameters zipParams = new ZipParameters();
            if (getPassword() != null
                    && !getPassword().trim().equalsIgnoreCase("")) {
                zipParams.setPassword(getPassword());
                zipParams.setEncryptFiles(true);
                zipParams
                        .setEncryptionMethod(Zip4jConstants.ENC_METHOD_STANDARD);

            }
            zipParams
                    .setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);

            if (sourceFile.exists()) {
                try {
                    zipFile = new ZipFile(getZipFileName());
                    if (zipFile.getFile().exists()) {
                        zipFile.addFile(sourceFile, zipParams);
                        if (log.isDebugEnabled()) {
                            log.debug("Adding: " + sourceFile.getName()
                                    + " to " + zipFile.getFile().getName()
                                    + " Pass: " + getPassword());
                        }
                    } else {
                        zipFile.createZipFile(sourceFile, zipParams);
                        if (log.isDebugEnabled()) {
                            log.debug("Creating: " + sourceFile.getName()
                                    + " to " + zipFile.getFile().getName()
                                    + " Pass: " + getPassword());
                        }
                    }
                } catch (ZipException e) {
                    log.error(e);
                    status = 1;
                }
            }
        }
    }

    return status;
}

我相信当多个线程尝试使用同一个 zip 文件时(可能在 zipFile.addFile(...)),您可能会有剩余或未压缩的文件。

因此,考虑到并发性,尝试以不同方式处理 addFile。

Their support forum 说这很棘手,目前不受支持 - 请参阅 link 了解这样做的局限性。

This can be quite tricky to implement, if not impossible to achieve, especially when using encryption or when compressing the file (and not just using the store method, which just copies the source file to the zip without any compression). A current block of file being compressed/decompressed depends on the previous block. So, if multiple threads were to read or write, these threads cannot do this process simultaneously, but have to wait until the block n-1 (if n is the current block) is read/wrote. So, its as good as running the process in the same thread.

Writing different files in different threads to a zip file (each thread handling a unique file in the zip) can be tricky as well. For example: AES encryption requires a unique number (as part of salt calculation) for each file in the zip. And another example: if a zip file is being created and multiple number of files being added (with compression), then the second thread, which will start writing the second file to the zip should know exactly at which location in the zip file to start writing, and this cannot be determined until the first thread is done writing.

Some compression algorithms, like LZMA/LZMA2, support multithreading. Unfortunately, these compression methods are not supported by Zip4j at the moment.

他们回复的全文(以防 post 被删除)。