[英]How to check if a generated zip file is corrupted?
我们有一段代码可以在我们的系统上生成一个zip文件。 一切正常,但有时该zip文件在由FilZip或WinZip打开时被视为已损坏。
所以这是我的问题:我们如何以编程方式检查生成的zip文件是否损坏?
这是我们用于生成zip文件的代码:
try {
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(tmpFile));
byte[] buffer = new byte[16384];
int contador = -1;
for (DigitalFile digitalFile : document.getDigitalFiles().getContent()) {
ZipEntry entry = new ZipEntry(digitalFile.getName());
FileInputStream fis = new FileInputStream(digitalFile.getFile());
try {
zos.putNextEntry(entry);
while ((counter = fis.read(buffer)) != -1) {
zos.write(buffer, 0, counter);
}
fis.close();
zos.closeEntry();
} catch (IOException ex) {
throw new OurException("It was not possible to read this file " + arquivo.getId());
}
}
try {
zos.close();
} catch (IOException ex) {
throw new OurException("We couldn't close this stream", ex);
}
我们在这里做错了什么吗?
编辑:实际上,上面的代码是绝对可以的。 我的问题是我正在为用户重定向WRONG流。 因此,与其打开一个zip文件,不如打开一个完全不同的文件。 Mea culpa :(
但是主要问题仍然存在: 如何以编程方式验证给定的zip文件是否未损坏?
您可以使用ZipFile
类来检查文件:
static boolean isValid(final File file) {
ZipFile zipfile = null;
try {
zipfile = new ZipFile(file);
return true;
} catch (IOException e) {
return false;
} finally {
try {
if (zipfile != null) {
zipfile.close();
zipfile = null;
}
} catch (IOException e) {
}
}
}
我知道已经发布了一段时间,我使用了大家提供的代码并提出了这个建议。 这对于实际问题非常有用。 检查zip文件是否已损坏
private boolean isValid(File file) {
ZipFile zipfile = null;
ZipInputStream zis = null;
try {
zipfile = new ZipFile(file);
zis = new ZipInputStream(new FileInputStream(file));
ZipEntry ze = zis.getNextEntry();
if(ze == null) {
return false;
}
while(ze != null) {
// if it throws an exception fetching any of the following then we know the file is corrupted.
zipfile.getInputStream(ze);
ze.getCrc();
ze.getCompressedSize();
ze.getName();
ze = zis.getNextEntry();
}
return true;
} catch (ZipException e) {
return false;
} catch (IOException e) {
return false;
} finally {
try {
if (zipfile != null) {
zipfile.close();
zipfile = null;
}
} catch (IOException e) {
return false;
} try {
if (zis != null) {
zis.close();
zis = null;
}
} catch (IOException e) {
return false;
}
}
}
我认为您会在生成zip文件的过程中看到相应的异常堆栈跟踪。 因此,您可能不希望增强异常处理。
在我的实现中,它看起来像那样。 也许它可以帮助您:
//[...]
try {
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
zos.putNextEntry(new ZipEntry(file.getName()));
try {
final byte[] buf = new byte[BUFFER_SIZE];
while (true) {
final int len = bis.read(buf);
if (len == -1) {
break;
}
zos.write(buf, 0, len);
}
zos.flush();
zos.closeEntry();
} finally {
try {
bis.close();
} catch (IOException e) {
LOG.debug("Buffered Stream closing failed");
} finally {
fis.close();
}
}
} catch (IOException e) {
throw new Exception(e);
}
//[...]
zos.close
new ZipFile(file)
再次压缩文件,所以重复的工作就不是您想要的。 尽管仅检查一个文件,但问题会压缩n个文件。
看看这个: http : //www.kodejava.org/examples/336.html
为您的邮政编码创建一个校验和:
CheckedOutputStream checksum = new CheckedOutputStream(fos, new CRC32());
ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(checksum));
...
当您完成压缩后,将其显示
System.out.println("Checksum : " + checksum.getChecksum().getValue());
您必须使用Java或其他工具以相同的方式读取zip,以检查校验和是否匹配。
也许交换以下两行?
fis.close();
zos.closeEntry();
我可以想象到closeEntry()仍然会从流中读取一些数据。
您的代码基本上可以,请尝试找出造成损坏的zip文件的文件。 检查digitalFile.getFile()是否始终向FileInputStream返回有效且可访问的参数。 只需在代码中添加一点日志记录,您就会发现问题所在。
ZipOutputStream 不会关闭基础流。
您需要做的是:
FileOutputStream fos = new FileOutputStream(...);
ZipOutputStream zos = new ZipOutputStream(fos);
然后在您的结尾处:
zos.close();
fos.flush(); // Can't remember whether this is necessary off the top of my head!
fos.close();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.