Java根据文件流准确判定文件类型

发布 : 2019-09-04 分类 : 轮子 浏览 :

判断文件类型通常可以简单的通过文件的后缀判定,如123.MP3,则判定文件的格式是MP3可播放文件。但是到底能不能播放,其实并不是通过后缀判断的。而是通过文件本身的二进制数据,软件来解析到底一定的目的。话不多说上代码,通过判断文件流的前几个字节,来判断文件的类型。可以自己添加新的类型,类型不一定对,可以自己调试调整一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
package com.ym.common.utils.qiniu;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

public class FileTypeHelper {

public final static Map<String, String> FILE_TYPE_MAP = new HashMap<String, String>();

private FileTypeHelper() {
}

static {
//初始化文件类型信息
getAllFileType();
}

/**
* Created on 2010-7-1
* <p>Discription:[getAllFileType,常见文件头信息]</p>
*
* @author:[shixing_11@sina.com]
*/
private static void getAllFileType() {
FILE_TYPE_MAP.put("jpg", "FFD8FF"); //JPEG (jpg)
FILE_TYPE_MAP.put("png", "89504E47"); //PNG (png)
FILE_TYPE_MAP.put("gif", "47494638"); //GIF (gif)
FILE_TYPE_MAP.put("tif", "49492A00"); //TIFF (tif)
FILE_TYPE_MAP.put("bmp", "424D"); //Windows Bitmap (bmp)
FILE_TYPE_MAP.put("dwg", "41433130"); //CAD (dwg)
FILE_TYPE_MAP.put("html", "68746D6C3E"); //HTML (html)
FILE_TYPE_MAP.put("rtf", "7B5C727466"); //Rich Text Format (rtf)
FILE_TYPE_MAP.put("xml", "3C3F786D6C");
FILE_TYPE_MAP.put("zip", "504B03041400000008005959104FFE4A759FF1");
FILE_TYPE_MAP.put("rar", "52617221");
FILE_TYPE_MAP.put("psd", "38425053"); //Photoshop (psd)
FILE_TYPE_MAP.put("eml", "44656C69766572792D646174653A"); //Email [thorough only] (eml)
FILE_TYPE_MAP.put("dbx", "CFAD12FEC5FD746F"); //Outlook Express (dbx)
FILE_TYPE_MAP.put("pst", "2142444E"); //Outlook (pst)
FILE_TYPE_MAP.put("xls", "D0CF11E0A1B11AE1000000000000000000000000000000003B"); //MS Word
FILE_TYPE_MAP.put("xlsx", "504B03041400060008000000210097454E26A"); //MS Word
FILE_TYPE_MAP.put("docx", "504B030414000600080000002100DFA4D26C5A"); //MS Excel 注意:word 和 excel的文件头一样
FILE_TYPE_MAP.put("pptx", "504B030414000600080000002100DFCC18F5AD");
FILE_TYPE_MAP.put("doc", "D0CF11E0A1B11AE1000000000000000000000000000000003E000300FEFF090006000000000000000000000001");
FILE_TYPE_MAP.put("ppt", "D0CF11E0A1B11AE1000000000000000000000000000000003E000300FEFF090006000000000000000000000003");
FILE_TYPE_MAP.put("mdb", "5374616E64617264204A"); //MS Access (mdb)
FILE_TYPE_MAP.put("wpd", "FF575043"); //WordPerfect (wpd)
FILE_TYPE_MAP.put("eps", "252150532D41646F6265");
FILE_TYPE_MAP.put("ps", "252150532D41646F6265");
FILE_TYPE_MAP.put("pdf", "255044462D312E"); //Adobe Acrobat (pdf)
FILE_TYPE_MAP.put("qdf", "AC9EBD8F"); //Quicken (qdf)
FILE_TYPE_MAP.put("pwl", "E3828596"); //Windows Password (pwl)
FILE_TYPE_MAP.put("wav", "57415645,52494646"); //Wave (wav)
FILE_TYPE_MAP.put("avi", "41564920");
FILE_TYPE_MAP.put("ram", "2E7261FD"); //Real Audio (ram)
FILE_TYPE_MAP.put("rm", "2E524D46"); //Real Media (rm)
FILE_TYPE_MAP.put("mpg", "000001BA"); //
FILE_TYPE_MAP.put("mov", "6D6F6F76"); //Quicktime (mov)
FILE_TYPE_MAP.put("asf", "3026B2758E66CF11"); //Windows Media (asf)
FILE_TYPE_MAP.put("mid", "4D546864"); //MIDI (mid)
FILE_TYPE_MAP.put("aac", "FFF15C4013"); //aac语音
FILE_TYPE_MAP.put("mp3", "FFE368"); //mp3
FILE_TYPE_MAP.put("webm", "1A45DFA39F42868101"); //webm
FILE_TYPE_MAP.put("m4a", "0000001C667479704D344120000000004D3441206D70"); //webm
}

/**
* 根据文件判定流类型
*
* @param file
* @return
*/
public final static String getFileTypeByFile(File file) {
InputStream is = null;
try {
is = new FileInputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return getFileTypeByStream(is);
}

/**
* 根据流判定文件类型
*
* @param is
* @return
*/
public final static String getFileTypeByStream(InputStream is) {
String filetype = null;
byte[] b = new byte[50];
try {
is.read(b);
filetype = getFileTypeByByte(b);
is.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return filetype;
}

/**
* Created on 2010-7-1
* <p>Discription:[getFileTypeByStream]</p>
*
* @param b
* @return fileType
* @author:[shixing_11@sina.com]
*/
public final static String getFileTypeByByte(byte[] b) {
String filetypeHex = String.valueOf(getFileHexString(b));
Iterator<Entry<String, String>> entryiterator = FILE_TYPE_MAP.entrySet().iterator();
while (entryiterator.hasNext()) {
Entry<String, String> entry = entryiterator.next();
String fileTypeHexValue = entry.getValue();
String[] split = fileTypeHexValue.split(",");
for (String sufix : split) {
if (filetypeHex.toUpperCase().startsWith(sufix)) {
return entry.getKey();
}
}
}
return "txt";
}

/**
* Created on 2010-7-1
* <p>Discription:[getFileHexString]</p>
*
* @param b
* @return fileTypeHex
* @author:[shixing_11@sina.com]
*/
private final static String getFileHexString(byte[] b) {
StringBuilder stringBuilder = new StringBuilder();
int byteLength = 50;
if (b == null || b.length <= 0) {
return null;
} else if (b.length < byteLength) {
byteLength = b.length;
}
for (int i = 0; i < byteLength; i++) {
int v = b[i] & 0xFF;
String hv = Integer.toHexString(v);
if (hv.length() < 2) {
stringBuilder.append(0);
}
stringBuilder.append(hv);
}
return stringBuilder.toString();
}
}

本文作者 : 625
原文链接 : https://www.kanchai.club/625/2019/09/04/Java根据文件流准确判定文件类型/
版权声明 : 本博客所有内容均供学习交流使用,转载请注明出处哦!

缺一盒火柴点火

微信扫一扫, 向我投食

微信扫一扫, 向我投食

支付宝扫一扫, 向我投食

支付宝扫一扫, 向我投食

留下足迹