admin 管理员组文章数量: 887021
2024年1月10日发(作者:网站网页设计的意义)
【黑马程序员】Java如何判断文件的真实类型
在我们实现一些需求的时候,有时候需要让用户上传文件,例如做论坛、社交类的应用和服务。这时候可能就会出现一个需求:上传固定类型、固定大小的文件,也就是说,只允许用户上传图片或者文本、压缩包等。其他的格式禁止上传,以防止用户恶意操作。文件的大小非常容易判断,主要是文件类型如何确定。
有一种方式是按照扩展名去判断,例如图片就是.jpg、.png等,但是这种方式不准确,因为如果真是恶意上传,exe文件也可以修改为上传成功。所以,必须要用一种方式获取文件的真实类型。即使文件后缀名修改了,也能找出来它的原形。
这个地方我们需要先了解一些基本知识,就是所有的文件的开头都有一段头信息,用来承担一定的任务,而每个不同类型的文件的头信息都是不同的,所以我们可以按照这种方式来进行判断。
首先,我们需要获取到文件头里这几个字节的数据,很简单,使用输入流来读取即可。代码如下:
01 public static String getFileHeader(String filePath) {
02 FileInputStream is = null;
03 String value = null;
04 try {
05 is = new FileInputStream(filePath);
06 byte[] b = new byte[4];
07 (b, 0, );
08 value = bytesToHexString(b);
09 } catch (Exception e) {
10 } finally {
11 if (null != is) {
12 try {
13 ();
14 } catch (IOException e) {
15 }
16 }
17 }
18 return value;
黑马程序员济南中心 编著
19 }
这个地方很容易理解,就是把文件的前4个byte取出来了,但是取出来的数据我们需要转换为16进制的字符串来表示,才能判断出来究竟是什么内容。接下来,我们就把数据转换一下。Integer里有一个API可以直接输出16进制的字符串,所以我们可以先把byte转换为integer来表示。由于byte是一个字节,而integer是4个字节,所以不足的部分用0填充,即用byte与0xFF做一次与运算,完成byte到integer的转换,然后把16进制的数据输出,字符串转换为大写以便后面使用。
01 private static String bytesToHexString(byte[] src) {
02 StringBuilder builder = new StringBuilder();
03 if (src == null || <= 0) {
04 return null;
05 }
06 String hv;
07 for (int i = 0; i < ; i++) {
08
// 以十六进制(基数 16)无符号整数形式返回一个整数参数的字09
符串表示形式,并转换为大写
10 hv = tring(src[i] & 0xFF).toUpperCase();
11 if (() < 2) {
12 (0);
13 }
14 (hv);
15 }
16 return ng();
}
得到了头信息里的数据之后,我们拿到的其实是一堆看上去像乱码的字符串,并不能黑马程序员济南中心 编著
判断出来究竟是什么类型的文件,所以我们需要搜集常见的文件类型的头信息都是什么,然后用映射关系表来查找。我这里准备了一些常用的文件的头信息,已经封装到了一个map里,可以参考。
01 public static final HashMap 02 String>(); 03 static { 04 // images 05 ("FFD8FF", "jpg"); 06 ("89504E47", "png"); 07 ("47494638", "gif"); 08 ("49492A00", "tif"); 09 ("424D", "bmp"); 10 // 11 ("41433130", "dwg"); // CAD 12 ("38425053", "psd"); 13 ("7B5C727466", "rtf"); // 日记本 14 ("3C3F786D6C", "xml"); 15 ("68746D6C3E", "html"); 16 ("44656C69766572792D646174653A", "eml"); // 邮件 17 ("D0CF11E0", "doc"); 18 ("D0CF11E0", "xls");// excel2003版本文件 19 ("5374616E64617264204A", "mdb"); 20 ("252150532D41646F6265", "ps"); 21 ("255044462D312E", "pdf"); 22 ("504B0304", "docx"); 23 ("504B0304", "xlsx");// excel2007以上版本文件 24 ("52617221", "rar"); 25 ("57415645", "wav"); 26 ("41564920", "avi"); 27 ("2E524D46", "rm"); 28 ("000001BA", "mpg"); 29 ("000001B3", "mpg"); 30 ("6D6F6F76", "mov"); 31 ("3026B2758E66CF11", "asf"); 32 ("4D546864", "mid"); 33 ("1F8B08", "gz"); } 黑马程序员济南中心 编著 这些都是一些固定的数据,我们现在有了map的key(其实就是上面我们最终获取到的字符串),直接去map里查找value就是文件的实际类型了。我们把一个png文件修改为试一下。打印结果是OK的。 这样,我们就可以把上面的代码整理封装为一个工具类来使用了,以后再处理文件上传的时候,就可以把一些恶意的操作屏蔽掉了。整体代码附到附件里自取吧。 黑马程序员济南中心 编著
版权声明:本文标题:【黑马程序员】Java如何判断文件的真实类型 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.freenas.com.cn/free/1704834437h463626.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论