本文共 10179 字,大约阅读时间需要 33 分钟。
魔数这个词在不同领域代表不同的含义。在计算机领域,魔数有两个含义,一指用来判断文件类型的魔数(magic number);二指程序代码中的魔数,也称魔法值。
不是所有文件都有文件头的。一个.txt类型的文件是一个纯文本文件,没有文件头。
参考文章:
项目中接到魔数校验的需求,这篇文章(Java 通过魔数判断上传文件的类型)对我理解很有帮助,在此基础上,我重新写了工具类的处理,通过文件路径或者文件流获取文件类型(文件类型与对应的文件魔数枚举类),然后通过 FileTypeEnum枚举类的数据再去根据需求处理不同的文件业务。
import org.apache.commons.lang3.StringUtils;/** * 文件类型与对应的文件魔数枚举类 */public enum FileTypeEnum { /** * JPEG (jpg) */ JPEG("JPG", "FFD8FF"), /** * PNG */ PNG("PNG", "89504E47"), /** * GIF */ GIF("GIF", "47494638"), /** * TIFF (tif) */ TIFF("TIF", "49492A00"), /** * Windows bitmap (bmp) */ BMP("BMP", "424D"), BMP_16("BMP", "424D228C010000000000"), //16色位图(bmp) BMP_24("BMP", "424D8240090000000000"), //24位位图(bmp) BMP_256("BMP", "424D8E1B030000000000"), //256色位图(bmp) /** * CAD (dwg) */ DWG("DWG", "41433130"), /** * Adobe photoshop (psd) */ PSD("PSD", "38425053"), /** * Rich Text Format (rtf) */ RTF("RTF", "7B5C727466"), /** * XML */ XML("XML", "3C3F786D6C"), /** * HTML (html) */ HTML("HTML", "68746D6C3E"), /** * Email [thorough only] (eml) */ EML("EML", "44656C69766572792D646174653A"), /** * Outlook Express (dbx) */ DBX("DBX", "CFAD12FEC5FD746F "), /** * Outlook (pst) */ PST("", "2142444E"), /** * doc;xls;dot;ppt;xla;ppa;pps;pot;msi;sdw;db */ OLE2("OLE2", "0xD0CF11E0A1B11AE1"), /** * Microsoft Word/Excel 注意:word 和 excel的文件头一样 */ XLS("XLS", "D0CF11E0"), /** * Microsoft Word/Excel 注意:word 和 excel的文件头一样 */ DOC("DOC", "D0CF11E0"), /** * Microsoft Word/Excel 2007以上版本文件 注意:word 和 excel的文件头一样 */ DOCX("DOCX", "504B0304"), /** * Microsoft Word/Excel 2007以上版本文件 注意:word 和 excel的文件头一样 504B030414000600080000002100 */ XLSX("XLSX", "504B0304"), /** * Microsoft Access (mdb) */ MDB("MDB", "5374616E64617264204A"), /** * Word Perfect (wpd) */ WPB("WPB", "FF575043"), /** * Postscript */ EPS("EPS", "252150532D41646F6265"), /** * Postscript */ PS("PS", "252150532D41646F6265"), /** * Adobe Acrobat (pdf) */ PDF("PDF", "255044462D312E"), /** * Quicken (qdf) */ QDF("qdf", "AC9EBD8F"), /** * QuickBooks Backup (qdb) */ QDB("qbb", "458600000600"), /** * Windows Password (pwl) */ PWL("PWL", "E3828596"), /** * ZIP Archive */ ZIP("", "504B0304"), /** * ARAR Archive */ RAR("", "52617221"), /** * WAVE (wav) */ WAV("WAV", "57415645"), /** * AVI */ AVI("AVI", "41564920"), /** * Real Audio (ram) */ RAM("RAM", "2E7261FD"), /** * Real Media (rm) rmvb/rm相同 */ RM("RM", "2E524D46"), /** * Real Media (rm) rmvb/rm相同 */ RMVB("RMVB", "2E524D46000000120001"), /** * MPEG (mpg) */ MPG("MPG", "000001BA"), /** * Quicktime (mov) */ MOV("MOV", "6D6F6F76"), /** * Windows Media (asf) */ ASF("ASF", "3026B2758E66CF11"), /** * ARJ Archive */ ARJ("ARJ", "60EA"), /** * MIDI (mid) */ MID("MID", "4D546864"), /** * MP4 */ MP4("MP4", "00000020667479706D70"), /** * MP3 */ MP3("MP3", "49443303000000002176"), /** * FLV */ FLV("FLV", "464C5601050000000900"), /** * 1F8B0800000000000000 */ GZ("GZ", "1F8B08"), /** * CSS */ CSS("CSS", "48544D4C207B0D0A0942"), /** * JS */ JS("JS", "696B2E71623D696B2E71"), /** * Visio */ VSD("VSD", "d0cf11e0a1b11ae10000"), /** * WPS文字wps、表格et、演示dps都是一样的 */ WPS("WPS", "d0cf11e0a1b11ae10000"), /** * torrent */ TORRENT("TORRENT", "6431303A637265617465"), /** * JSP Archive */ JSP("JSP", "3C2540207061676520"), /** * JAVA Archive */ JAVA("JAVA", "7061636B61676520"), /** * CLASS Archive */ CLASS("CLASS", "CAFEBABE0000002E00"), /** * JAR Archive */ JAR("JAR", "504B03040A000000"), /** * MF Archive */ MF("MF", "4D616E69666573742D56"), /** * EXE Archive */ EXE("EXE", "4D5A9000030000000400"), /** * ELF Executable */ ELF("ELF", "7F454C4601010100"), /** * Lotus 123 v1 */ WK1("WK1", "2000604060"), /** * Lotus 123 v3 */ WK3("WK3", "00001A0000100400"), /** * Lotus 123 v5 */ WK4("WK4", "00001A0002100400"), /** * Lotus WordPro v9 */ LWP("LWP", "576F726450726F"), /** * Sage(sly.or.srt.or.slt;sly;srt;slt) */ SLY("SLY", "53520100"), /** * CHM Archive */ /* CHM("CHM", "49545346030000006000"), INI("INI", "235468697320636F6E66"), SQL("SQL", "494E5345525420494E54"), BAT("BAT", "406563686F206f66660D"), PROPERTIES("", "6C6F67346A2E726F6F74"), MXP("", "04000000010000001300"), */ NOT_EXITS_ENUM("", ""); /** * 文件类型对应的名称 */ private String fileTypeName; /** * 文件类型对应的魔数 */ private String magicNumberCode; private FileTypeEnum(String fileTypeName, String magicNumberCode) { this.fileTypeName = fileTypeName; this.magicNumberCode = magicNumberCode; } public String getFileTypeName() { return fileTypeName; } public String getMagicNumberCode() { return magicNumberCode; } /** * 根据文件类型获取文件类型魔数编码 * 默认返回标准件 * * @param magicNumberCode - 文件类型魔数编码 * @return */ public static FileTypeEnum getByMagicNumberCode(String magicNumberCode) { if (StringUtils.isNotBlank(magicNumberCode)) { for (FileTypeEnum type : values()) { if (magicNumberCode.toUpperCase().startsWith(type.getMagicNumberCode())) { return type; } } } return FileTypeEnum.NOT_EXITS_ENUM; } /** * 根据文件类型后缀名获取枚举 * * @param fileTypeName - 文件类型后缀名 * @return */ public static FileTypeEnum getByFileTypeName(String fileTypeName) { if (StringUtils.isNotBlank(fileTypeName)) { for (FileTypeEnum type : values()) { if (type.getFileTypeName().equals(fileTypeName)) { return type; } } } return FileTypeEnum.NOT_EXITS_ENUM; }}
import cn.jq.javademo.utils.pojo.FileTypeEnum;import org.apache.commons.lang3.StringUtils;import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;/** * 文件类型与对应的文件魔数处理工具类 */public class FileTypeUtil { public static void main(String[] args) throws Exception { File fromPic = new File("D:\\E\\电脑壁纸\\JD导入.xlsx"); FileTypeEnum fileTypeEnum = FileTypeUtil.getFileTypeByInputStream(new FileInputStream(fromPic)); System.out.println(fileTypeEnum.getFileTypeName()); System.out.println(fileTypeEnum.getMagicNumberCode()); System.out.println(fileTypeEnum); FileTypeEnum fileTypeEnum2 = FileTypeUtil.getFileTypeByPath("D:\\E\\电脑壁纸\\598a80e12f9ad.jpg"); System.out.println(fileTypeEnum2.getFileTypeName()); System.out.println(fileTypeEnum2.getMagicNumberCode()); System.out.println(fileTypeEnum2); } /** * 通过文件路径获取文件类型 * @param path * @return FileTypeEnum - 文件类型与对应的文件魔数枚举类 */ public static FileTypeEnum getFileTypeByPath(String path) { // 获取文件头 String magicNumberCode = magicNumberCode = getFileHeaderHexByPath(path); if (StringUtils.isNotBlank(magicNumberCode)) { return FileTypeEnum.getByMagicNumberCode(magicNumberCode.toUpperCase()); } return FileTypeEnum.NOT_EXITS_ENUM; } /** * 通过文件流获取文件类型 * @param inputStream * @return FileTypeEnum - 文件类型与对应的文件魔数枚举类 */ public static FileTypeEnum getFileTypeByInputStream(InputStream inputStream) { // 获取文件头 String magicNumberCode = getFileHeaderHexByInputStream(inputStream); if (StringUtils.isNotBlank(magicNumberCode)) { return FileTypeEnum.getByMagicNumberCode(magicNumberCode.toUpperCase()); } return FileTypeEnum.NOT_EXITS_ENUM; } /** * 获取文件头(即文件魔数),根据文件路径 * @param path * @return fileHeaderHex - 文件头,即文件魔数 */ public static String getFileHeaderHexByPath(String path){ byte[] b = new byte[28]; InputStream inputStream = null; try { inputStream = new FileInputStream(path); inputStream.read(b, 0, 28); } catch (IOException e) { e.printStackTrace(); return null; } finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } return bytesToHexString(b); } /** * 获取文件头(即文件魔数),根据通过文件流 * @param inputStream * @return fileHeaderHex - 文件头,即文件魔数 */ public static String getFileHeaderHexByInputStream(InputStream inputStream) { byte[] b = new byte[28]; try { inputStream.read(b, 0, 28); } catch (IOException e) { e.printStackTrace(); return null; } finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } return bytesToHexString(b); } /** * 将文件二进制流(即字节数组)转换成16进制字符串数据 * @param b * @return fileHeaderHex - 文件头,即文件魔数 */ private final static String bytesToHexString(byte[] b) { StringBuilder stringBuilder = new StringBuilder(); if (b == null || b.length <= 0) { return null; } for (int i = 0; i < b.length; i++) { int v = b[i] & 0xFF; String hv = Integer.toHexString(v); if (hv.length() < 2) { stringBuilder.append(0); } stringBuilder.append(hv); } return stringBuilder.toString(); }}
—— Stay Hungry. Stay Foolish. 求知若饥,虚心若愚。
转载地址:http://mgdgn.baihongyu.com/