using System.Text; namespace Common.Util { /// /// 验证文件类型 /// public static class VerifyFileExtensionName { private static readonly IDictionary dics_ext = new Dictionary(); private static readonly IDictionary> ext_dics = new Dictionary>(); static VerifyFileExtensionName() { dics_ext.Add("FFD8FFE0", ".jpg"); dics_ext.Add("FFD8FFE1", ".jpg"); dics_ext.Add("89504E47", ".png"); dics_ext.Add("47494638", ".gif"); dics_ext.Add("49492A00", ".tif"); dics_ext.Add("424D", ".bmp"); // PS和CAD dics_ext.Add("38425053", ".psd"); dics_ext.Add("41433130", ".dwg"); // CAD dics_ext.Add("252150532D41646F6265", ".ps"); // 办公文档类 dics_ext.Add("D0CF11E0", ".ppt,.doc,.xls"); // ppt、doc、xls dics_ext.Add("504B0304", ".pptx,.docx,.xlsx"); // pptx、docx、xlsx /* 注意由于文本文档录入内容过多,则读取文件头时较为多变-START */ dics_ext.Add("0D0A0D0A", ".txt"); // txt dics_ext.Add("0D0A2D2D", ".txt"); // txt dics_ext.Add("0D0AB4B4", ".txt"); // txt dics_ext.Add("B4B4BDA8", ".txt"); // 文件头部为汉字 dics_ext.Add("73646673", ".txt"); // txt,文件头部为英文字母 dics_ext.Add("32323232", ".txt"); // txt,文件头部内容为数字 dics_ext.Add("0D0A09B4", ".txt"); // txt,文件头部内容为数字 dics_ext.Add("3132330D", ".txt"); // txt,文件头部内容为数字 /* 注意由于文本文档录入内容过多,则读取文件头时较为多变-END */ dics_ext.Add("7B5C727466", ".rtf"); // 日记本 dics_ext.Add("255044462D312E", ".pdf"); // 视频或音频类 dics_ext.Add("3026B275", ".wma"); dics_ext.Add("57415645", ".wav"); dics_ext.Add("41564920", ".avi"); dics_ext.Add("4D546864", ".mid"); dics_ext.Add("2E524D46", ".rm"); dics_ext.Add("000001BA", ".mpg"); dics_ext.Add("000001B3", ".mpg"); dics_ext.Add("6D6F6F76", ".mov"); dics_ext.Add("3026B2758E66CF11", ".asf"); // 压缩包 dics_ext.Add("52617221", ".rar"); dics_ext.Add("504B03040A000000", ".zip"); dics_ext.Add("1F8B08", ".gz"); // 程序文件 dics_ext.Add("3C3F786D6C", ".xml"); dics_ext.Add("68746D6C3E", ".html"); //dics_ext.Add("7061636B", ".java"); //dics_ext.Add("3C254020", ".jsp"); //dics_ext.Add("4D5A9000", ".exe"); dics_ext.Add("44656C69766572792D646174653A", ".eml"); // 邮件 dics_ext.Add("5374616E64617264204A", ".mdb"); // Access数据库文件 dics_ext.Add("46726F6D", ".mht"); dics_ext.Add("4D494D45", ".mhtml"); foreach (var dics in dics_ext) { foreach (var ext in dics.Value.Split(",")) { if (!ext_dics.ContainsKey(ext)) ext_dics.Add(ext, new HashSet { dics.Key.Length / 2 }); else ext_dics[ext].Add(dics.Key.Length / 2); } } } /// /// 文件格式和文件内容格式是否一致 /// /// /// /// public static bool IsSameType(Stream stream, string suffix = ".jpg") { if (stream == null) return false; suffix = suffix.ToLower(); if (!ext_dics.ContainsKey(suffix)) return false; try { foreach (var Len in ext_dics[suffix]) { byte[] b = new byte[Len]; stream.Read(b, 0, b.Length); // string fileType = System.Text.Encoding.UTF8.GetString(b); string fileKey = GetFileHeader(b); if (dics_ext.ContainsKey(fileKey)) return true; } } catch (IOException) { } return false; } /** * 根据文件转换成的字节数组获取文件头信息 * @param 文件路径 * @return 文件头信息 */ private static string GetFileHeader(byte[] b) { string value = BytesToHexString(b); return value; } /** * 将要读取文件头信息的文件的byte数组转换成string类型表示 * 下面这段代码就是用来对文件类型作验证的方法, * 将字节数组的前四位转换成16进制字符串,并且转换的时候,要先和0xFF做一次与运算。 * 这是因为,整个文件流的字节数组中,有很多是负数,进行了与运算后,可以将前面的符号位都去掉, * 这样转换成的16进制字符串最多保留两位,如果是正数又小于10,那么转换后只有一位, * 需要在前面补0,这样做的目的是方便比较,取完前四位这个循环就可以终止了 * @param src要读取文件头信息的文件的byte数组 * @return 文件头信息 */ private static string BytesToHexString(byte[] src) { var builder = new StringBuilder(); if (src == null || src.Length <= 0) return null; string hv; for (int i = 0; i < src.Length; i++) { // 以十六进制(基数 16)无符号整数形式返回一个整数参数的字符串表示形式,并转换为大写 hv = Convert.ToString(src[i] & 0xFF, 16).ToUpper(); if (hv.Length < 2) builder.Append(0); builder.Append(hv); } return builder.ToString(); } } }