java 如何在java中识别zip文件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33934178/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to identify a zip file in java?
提问by Hyman
I want to identify my archive whether it is zip
or rar
. But the problem I get runtime error before I can validate my file. I want to create custom notification:
我想确定我的档案是zip
还是rar
. 但是我在验证文件之前遇到运行时错误的问题。我想创建自定义通知:
public class ZipValidator {
public void validate(Path pathToFile) throws IOException {
try {
ZipFile zipFile = new ZipFile(pathToFile.toFile());
String zipname = zipFile.getName();
} catch (InvalidZipException e) {
throw new InvalidZipException("Not a zip file");
}
}
}
At the moment I have runtime error:
目前我有运行时错误:
java.util.zip.ZipException: error in opening zip file
java.util.zip.ZipException:打开 zip 文件时出错
回答by bratkartoffel
I'd suggest to open a plain InputStream an reading the first few bytes (magic bytes) and not to rely on the file extension as this can be easily spoofed. Also, you can omit the overhead creating and parsing the files.
我建议打开一个普通的 InputStream 读取前几个字节(魔术字节),不要依赖文件扩展名,因为这很容易被欺骗。此外,您可以省略创建和解析文件的开销。
For RAR the first bytes should be 52 61 72 21 1A 07.
对于 RAR,第一个字节应该是52 61 72 21 1A 07。
For ZIP it should be one of:
对于 ZIP,它应该是以下之一:
- 50 4B 03 04
- 50 4B 05 06(empty archive)
- 50 4B 07 08(spanned archive).
- 50 4B 03 04
- 50 4B 05 06(空存档)
- 50 4B 07 08(跨存档)。
Source: https://en.wikipedia.org/wiki/List_of_file_signatures
来源:https: //en.wikipedia.org/wiki/List_of_file_signatures
Another point, just looked at your code:
还有一点,只是看了你的代码:
Why do you catch die InvalidZipException, throw it away and construct a new one? This way you lose all the information from the original exception, making it hard to debug and understand what exactly went wrong. Either don't catch it at all or, if you have to wrap it, do it right:
为什么你会捕捉到 InvalidZipException,扔掉它并构建一个新的?这样,您会丢失原始异常中的所有信息,从而难以调试和了解究竟出了什么问题。要么根本不抓住它,要么,如果必须包装它,请正确处理:
} catch (InvalidZipException e) {
throw new InvalidZipException("Not a zip file", e);
}
回答by Fabian Braun
Merging the answers of nanda & bratkartoffel.
合并 nanda 和 bratkartoffel 的答案。
private static boolean isArchive(File f) {
int fileSignature = 0;
try (RandomAccessFile raf = new RandomAccessFile(f, "r")) {
fileSignature = raf.readInt();
} catch (IOException e) {
// handle if you like
}
return fileSignature == 0x504B0304 || fileSignature == 0x504B0506 || fileSignature == 0x504B0708;
}
回答by nanda
RandomAccessFile raf = new RandomAccessFile(f, "r");
long n = raf.readInt();
raf.close();
if (n == 0x504B0304)
????System.out.println("Should be a zip file");
else
????System.out.println("Not a zip file");
You can see it in the following link. http://www.coderanch.com/t/381509/java/java/check-file-zip-file-java
您可以在以下链接中看到它。 http://www.coderanch.com/t/381509/java/java/check-file-zip-file-java
回答by hatze
Exception is thrown in line
异常被抛出
ZipFile zipFile = new ZipFile(pathToFile.toFile());
That's because if a non-ZipFile is given as parameter for the ZipFile
constructor the ZipException
is thrown.
So you have to check beforegenerating a new ZipFile
Object if your file path points to a correct ZipFile
.
One solution might be to check the extension of the file path like so
那是因为如果将非 ZipFile 作为ZipFile
构造函数的参数给出,ZipException
则抛出。因此,您必须在生成新ZipFile
对象之前检查您的文件路径是否指向正确的ZipFile
. 一种解决方案可能是像这样检查文件路径的扩展名
PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:*.zip");
boolean extensionCorrect = matcher.matches(path);