zip4j是一个很棒的图书馆。但是在使用线程的类中使用它时会遇到问题。 zip4j方法是从一个实现线程的类中调用的,有时(并不总是)它会使文件解压缩,而且有些左下角文件的扩展名为* .zip345。此过程还返回net.lingala.zip4j.exception.ZipException:无法重命名已修改的zip文件。
从类public方法调用zip4jProcess方法。班级名称为:SZipInterface.class
SZipInterface.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;
}
答案 0 :(得分:0)
我相信当你有多个线程试图使用相同的zip文件(可能是在zipFile.addFile(...))时,剩余或未压缩文件的时间可能是这样。
因此,尝试以不同的方式处理addFile并考虑并发性。
Their support forum说这很棘手,目前还不支持 - 请参阅链接了解这样做的局限性。
如果不是不可能实现,这可能非常棘手, 特别是在使用加密或压缩文件时(而不是 只使用store方法,它只是将源文件复制到 拉链没有任何压缩)。当前的文件块 压缩/解压缩取决于前一个块。所以,如果多个 线程被读或写,这些线程不能做这个过程 同时,但必须等到块n-1(如果n是 读取/写入当前块。所以,它与运行流程一样好 在同一个主题中。
将不同线程中的不同文件写入zip文件(每个文件 线程处理zip中的唯一文件也很棘手。对于 示例:AES加密需要一个唯一的编号(作为salt的一部分) 压缩邮件中的每个文件。另一个例子:如果拉链 正在创建文件并添加了多个文件(使用 压缩),然后是第二个线程,它将开始写入 zip的第二个文件应该确切地知道在哪个位置 zip文件开始写,直到这个都无法确定 第一个线程完成了写作。
某些压缩算法(如LZMA / LZMA2)支持多线程。 不幸的是,Zip4j不支持这些压缩方法 那一刻。
他们的回复全文(如果帖子被删除)。