-1

zip4j 是一个很棒的库。但是我在使用线程的类中使用它时遇到了问题。zip4j 方法是从实现线程的类中调用的,有时(并非总是)它会使文件解压缩,有时会有扩展名为 *.zip345 的leftofer 文件。该过程还返回 net.lingala.zip4j.exception.ZipException: cannot rename modified zip 文件。

方法 zip4jProcess 是从类公共方法中调用的。班级名称是:SZipInterface.class

SZipInterface.class线程类中初始化,例如: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;
}
4

1 回答 1

0

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

因此,请尝试在考虑并发的情况下以不同的方式处理 addFile。

他们的支持论坛说这很棘手并且目前不支持 - 请参阅链接以了解这样做的限制。

这可能很难实现,如果不是不可能实现的话,尤其是在使用加密或压缩文件时(而不仅仅是使用 store 方法,它只是将源文件复制到 zip 而不进行任何压缩)。当前正在压缩/解压缩的文件块取决于前一个块。因此,如果多个线程要读取或写入,这些线程不能同时执行此过程,而是必须等到块 n-1(如果 n 是当前块)被读取/写入。因此,它与在同一个线程中运行进程一样好。

将不同线程中的不同文件写入 zip 文件(每个线程处理 zip 中的唯一文件)也可能很棘手。例如:AES 加密要求 zip 中的每个文件都有一个唯一编号(作为盐计算的一部分)。另一个例子:如果正在创建一个 zip 文件并添加多个文件(使用压缩),那么将开始将第二个文件写入 zip 的第二个线程应该确切知道从 zip 文件中的哪个位置开始写入,并且在第一个线程完成写入之前无法确定。

一些压缩算法,如 LZMA/LZMA2,支持多线程。不幸的是,Zip4j 目前不支持这些压缩方法。

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

于 2015-06-16T12:26:20.400 回答