获取文件头信息进行文件类型识别验证
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
/**
* 获取文件头信息进行文件类型识别验证
* Created by 张勇波 on 2017/12/19.
*/
public class CheckFileTypeUtil {
public static void main(String[] args) {
//final String fileType = getFileType("/Users/ZYB/Downloads/工作日志.xls");
//final String fileType = getFileType("/Users/ZYB/Pictures/小草1.jpg");
//final String fileType = getFileType("/Users/ZYB/Downloads/发布其他部门文章选择流程审核需求.docx");
//final String fileType = getFileType("/Users/ZYB/workspace/DFWH/模版/cms模版/监狱.zip");
//final String fileType = getFileType("/Users/ZYB/workspace/IdeaProjects_assoft/cms6.7/manageweb/WebContent/bs/edit/content/pages/flash.htm");
// final String fileType = getFileType("/Users/ZYB/Downloads/图片上传/可上传图片/可传5.jpg");
final String fileType = getFileType("/Users/ZYB/Downloads/图片上传/无法上传的图片/不可传2.jpg");
// final String fileType = getFileType("/Users/ZYB/Downloads/图片上传/test.bmp");
// final String fileType = getFileType("/Users/ZYB/Downloads/图片上传/可传视频1.mp4");
System.out.println(fileType);
}
// 缓存文件头信息-文件头信息
// 3个字节长度的头信息
public static final HashMap<String, String> mFileTypes = new HashMap<String, String>();
static {
mFileTypes.put("FFD8FF", "jpg");
mFileTypes.put("89504E", "png");
mFileTypes.put("474946", "gif");
mFileTypes.put("424D36", "bmp");
//mFileTypes.put("CAFEBA", "class");
mFileTypes.put("3C3F78", "xml");
mFileTypes.put("3C2144", "html");
mFileTypes.put("EFBBBF", "htm");
//mFileTypes.put("4D5A50", "exe");
mFileTypes.put("255044", "pdf");
mFileTypes.put("7B5C72", "rtf");
mFileTypes.put("D0CF11", "doc/xls/ppt/...");
mFileTypes.put("504B03", "docx/xlsx/pptx/jar/zip/...");
mFileTypes.put("526172", "rar");
mFileTypes.put("494433", "mp3");
mFileTypes.put("3026B2", "wmv");
mFileTypes.put("524946", "avi");
mFileTypes.put("000000", "mp4");
mFileTypes.put("464C56", "flv");
}
/**
* 根据文件路径获取文件头信息
*
* @param file 文件路径/File对象
* @return 类型
*/
public static String getFileType(Object file) {
if (file != null) {
String code;
File file1;
if (file instanceof File) {
file1 = (File) file;
} else {
file1 = new File((String) file);
}
if (file1.exists()) {
code = getFileHeader(file1, 3);
System.out.println(code);
String fileType = mFileTypes.get(code);
if (fileType == null) {
String fileName = file1.getName().toLowerCase();
String filename = file1.getName().toLowerCase()
.replaceAll("\\/|\\/|\\||:|\\?|\\*|\"|<|>|\\p{Cntrl}", "");
if (fileName.equals(filename) && !fileName.contains("%00") && !fileName.contains("0x00")) {
//没有固定文件头信息的例外文件
if (fileName.endsWith(".txt") || fileName.endsWith(".swf"))
fileType = "additionalDocuments";
}
}
return fileType;
} else {
return null;
}
}
return null;
}
/**
* 根据文件对象获取文件指定字节长度的头信息
*
* @param file 文件对象
* @param length 读取文件字节长度
* @return 文件头信息
*/
public static String getFileHeader(File file, int length) {
FileInputStream is = null;
String value = null;
try {
is = new FileInputStream(file);
byte[] b = new byte[length];
//read(byte[] b, int off, int len)从此输入流中将最多 len 个字节的数据读入一个 byte 数组中。
is.read(b, 0, b.length);
value = bytesToHexString(b);
} catch (Exception e) {
} finally {
if (null != is) {
try {
is.close();
} catch (IOException e) {
}
}
}
return value;
}
/**
* 将byte数组转换成 以十六进制(基数 16)无符号整数形式,并转换为大写
*
* @param src 文件头信息的byte数组
* @return 文件头信息
*/
private static String bytesToHexString(byte[] src) {
StringBuilder builder = new StringBuilder();
if (src == null || src.length <= 0) {
return null;
}
String hv;
for (int i = 0; i < src.length; i++) {
// 以十六进制(基数 16)无符号整数形式返回一个整数参数的字符串表示形式,并转换为大写
hv = Integer.toHexString(src[i] & 0xFF).toUpperCase();
//一个byte数据要转换为两位的十六进制数。但是有时候& 0xFF之后得到的值是一位,所以要补零
if (hv.length() < 2) {
builder.append(0);
}
builder.append(hv);
}
return builder.toString();
}
}