前言
在上传图片文件的时候除了需要限制文件的大小,通常还需要对文件类型进行判断。因为用户可能会上传任何东西上来,如果被有心人上传木马到你服务器那就麻烦了。
Java检查文件类型的方法
判断文件后缀名
String extension = "";
int i = fileName.lastIndexOf('.');
if (i > 0) {
extension = fileName.substring(i+1);
}
//...
if("jpg".equals(extension)){
//your code
}
但是这种方法不太靠谱
判断文件头
在后缀未知,或者后缀被修改的文件,依然通过文件头来判断该文件究竟是什么文件类型。我们可以使用一个文本编辑工具如UltraEdit打开文件(16进制模式下),然后看文件头是什么字符,以下是常见图片类型的文件头字符(16进制)
JPEG (jpg),文件头:FFD8FF
PNG (png),文件头:89504E47
GIF (gif),文件头:47494638
TIFF (tif),文件头:49492A00
Windows Bitmap (bmp),文件头:424D
通过MimetypesFileTypeMap来判断
public class ImageCheck {
private MimetypesFileTypeMap mtftp;
public ImageCheck(){
mtftp = new MimetypesFileTypeMap();
/* 不添加下面的类型会造成误判 详见:http://stackoverflow.com/questions/4855627/java-mimetypesfiletypemap-always-returning-application-octet-stream-on-android-e*/
mtftp.addMimeTypes("image png tif jpg jpeg bmp");
}
public boolean isImage(File file){
String mimetype= mtftp.getContentType(file);
String type = mimetype.split("/")[0];
return type.equals("image");
}
}
该方法貌似是基于文件后缀进行判断的,修改文本文件后缀为jpg,也会返回true。
通过ImageIO来判断
try {
// 通过ImageReader来解码这个file并返回一个BufferedImage对象
// 如果找不到合适的ImageReader则会返回null,我们可以认为这不是图片文件
// 或者在解析过程中报错,也返回false
Image image = ImageIO.read(file);
return image != null;
} catch(IOException ex) {
return false;
}
注意: 该方法适用的图片格式为 bmp/gif/jpg/png
测试
测试不同的方法
public class ImageCheckerTest {
private File imageFile;//真正的图片文件 图片
private File txt2ImageFile; //将txt后缀改为jpg txt
private File image2txt;//将图片文件后缀改为txt 图片
@Before
public void init(){
imageFile = new File("D:\\image.jpg");
txt2ImageFile = new File("D:\\txt.jpg");
image2txt = new File("D:\\image.txt");
}
@Test
public void test1(){
MimetypesFileTypeMap mtftp = new MimetypesFileTypeMap();
mtftp.addMimeTypes("image png tif jpg jpeg bmp");
String mimetype = mtftp.getContentType(imageFile);
String type = mimetype.split("/")[0];
assertTrue(type.equals("image"));
mimetype = mtftp.getContentType(txt2ImageFile);
type = mimetype.split("/")[0];
assertFalse(type.equals("image"));
mimetype = mtftp.getContentType(image2txt);
type = mimetype.split("/")[0];
assertTrue(type.equals("image"));
}
@Test
public void test2() throws IOException {
String mimetype = Files.probeContentType(imageFile.toPath());
String type = mimetype.split("/")[0];
assertTrue(type.equals("image"));
mimetype = Files.probeContentType(txt2ImageFile.toPath());
type = mimetype.split("/")[0];
assertFalse(type.equals("image"));
mimetype = Files.probeContentType(image2txt.toPath());
type = mimetype.split("/")[0];
assertTrue(type.equals("image"));
}
@Test
public void test3() {
FileNameMap fileNameMap = URLConnection.getFileNameMap();
String type = fileNameMap.getContentTypeFor(imageFile.getAbsolutePath()).split("/")[0];
assertTrue(type.equals("image"));
type = fileNameMap.getContentTypeFor(txt2ImageFile.getAbsolutePath()).split("/")[0];
assertFalse(type.equals("image"));
type = fileNameMap.getContentTypeFor(image2txt.getAbsolutePath()).split("/")[0];
assertTrue(type.equals("image"));
}
@Test
public void test4() throws IOException {
assertTrue(check4(imageFile));
assertFalse(check4(txt2ImageFile));
assertTrue(check4(image2txt));
}
public boolean check4(File file){
try {
Image image = ImageIO.read(file);
return image != null;
} catch(IOException ex) {
return false;
}
}
}
我准备了3个文件,第1个是真正的图片文件,第2个是后缀为jpg的文本文件,第3个为后缀是txt的图片文件
测试结果如下:
只有第4个测试用例成功的。其他的都死在对第2个文件的判断上了,我把对第2个文件的判断代码都删掉,结果又死在对第3个文件的判断上了。
测试不同的图片格式
接下来测试方法4能适用的图片格式:
通过图片转换器将jpg图片转换为下面的格式:
public class ImageCheckerTest {
private File path;
@Before
public void init(){
path = new File("D:\\images");
}
public boolean check4(File file){
try {
Image image = ImageIO.read(file);
return image != null;
} catch(IOException ex) {
return false;
}
}
@Test
public void testImageType() {
File[] files = path.listFiles();
for (File file : files){
System.out.println("Check file: " + file.getName() +" : " + check4(file));
}
}
}
结果如下:
Check file: image.bmp : true
Check file: image.dcx : false
Check file: image.gif : true
Check file: image.ico : false
Check file: image.j2k : false
Check file: image.jp2 : false
Check file: image.jpg : true
Check file: image.pcx : false
Check file: image.png : true
Check file: image.psd : false
Check file: image.tga : false
Check file: image.tif : false
该方法适用的图片格式为:bmp/gif/jpg/png
总结
如果对安全性和图片格式完整性要求高的话建议使用第三方jar包。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:http://bianchenghao.cn/39011.html