前言
之前『利用 Magic Number 校验文件类型』一文讲解了校验文件类型的原理,并在文末给出了示例代码。但是每次去查询 Magic Number 对照表有点麻烦,于是我找了一些能够判断文件类型的三方库,可以省不少事儿。
作为开发者你应该知道,在 HTTP 协议消息头中,使用 Content-Type
来表示请求和响应中的媒体类型信息。这个字段在不同场景下有几种叫法,Content Type、Media Type、MIME Type,严格来说这几个名称并不完全对等,但在这里我们暂不做区分,大家明白意思就行。
它用来告诉服务端如何处理请求的数据,以及告诉客户端如何解析响应的数据。
因此我们可以通过这个值来判断文件类型。
URLConnection
URLConnection
是 JDK 自带的类,它相当于 URL 资源与应用程序之间的桥梁。它是一个抽象类,我们熟知的 HttpURLConnection
就是它的子类。
public class FileMatcher {
private static final String MIME_TYPE_PNG = "image/png";
public static boolean isPng(File file) {
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
String mime = URLConnection.guessContentTypeFromStream(fis);
return MIME_TYPE_PNG.equals(mime);
} catch (IOException e) {
return false;
} finally {
try {
if (fis != null) {
fis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
通过 guessContentTypeFromStream()
方法获取流的 Content Type,再与对应的 Media Type 比较即可。
另外 URLConnection
还有一个 guessContentTypeFromName()
方法,是根据文件名来判断,也就是之前说的通过文件扩展名,这种方法并不可靠,但是速度会快一些。
jMimeMagic
jMimeMagic 是一个用于确定文件或数据流的 MIME Type 的 Java 库。
添加依赖:
dependencies {
implementation 'net.sf.jmimemagic:jmimemagic:0.1.5'
}
逻辑代码:
public class FileMatcher {
private static final String MIME_TYPE_PNG = "image/png";
public static boolean isPng(File file) {
try {
MagicMatch match = Magic.getMagicMatch(file, false);
String mime = match.getMimeType();
return MIME_TYPE_PNG.equals(mime);
} catch (MagicParseException | MagicMatchNotFoundException | MagicException e) {
return false;
}
}
}
可惜的是该库的上一次更新还停留在 2017 年。
Apache Tika Core
Apache Tika 工具包可检测和提取上千种不同文件类型中的元数据和文本。
依赖核心库即可:
dependencies {
implementation 'org.apache.tika:tika-core:2.8.0'
}
逻辑代码:
public class FileMatcher {
private static final String MIME_TYPE_PNG = "image/png";
public static boolean isPng(File file) {
Tika tika = new Tika();
try {
String mime = tika.detect(file);
return MIME_TYPE_PNG.equals(mime);
} catch (IOException e) {
return false;
}
}
}
有 Apache 做背书,只能说稳得一匹。
后记
可以看到,这几种方法都是通过读取数据流的方式来校验文件类型,和之前『利用 Magic Number 校验文件类型』介绍的原理是一致的,同时由于这几种方法都能够处理数据流,所以并非只能传入 File
,在网络传输数据流时也能够很方便地进行校验。