这是去年一个WPF项目中写的一个用于识别文件类型的辅助类,主要用于检测一些常用的文件格式吗
注意: 该类已经在实际的产品被运用,但是作者依然不能保证该辅助类在实际文件中的检测百分百的正确,使用过程请谨慎!
1. 图像: jpg,bmp,png,jpeg,gif等
2. 视频: MP4,AVI,RMVB,FLV,SWF,RM,WMV
3. 音频:MP3,WMA,WAV,MID,MIDI
/// <summary> /// 文件类型 /// </summary> public enum ResourceType { /// <summary> /// 图片资源 /// </summary> Image, /// <summary> /// 视频资源 /// </summary> Video, /// <summary> /// 音频资源 /// </summary> Audio, /// <summary> /// 动画资源 /// </summary> Flash, /// <summary> /// 未知 /// </summary> Unknown }
/// <summary> /// 文件类型识别辅助类</ BY andy1987 /> /// </summary> public static class FileUtility { #region 静态变量 private static List<string> IMAGE_EXTENSIONS = new List<string> { ".GIF",".PNG",".BMP",".TIFF",".WMF",".EMP",".ICO",".JPG",".JPEG" }; private static List<string> VIDEO_EXTENSION = new List<string> { ".MP4",".AVI",".RMVB",".FLV",".SWF",".RM",".WMV" }; private static List<string> AUDIO_EXTENSION = new List<string> { ".MP3",".WMA",".WAV",".MID",".MIDI" }; #endregion #region 图片 public static ImageType GetImageType(System.IO.Stream stream) { //从文件流中读取前8个字节,然后根据各种图片资源magic number //比较确定图片文件格式 byte[] header = new byte[8]; stream.Seek(0, SeekOrigin.Begin); if (stream.Read(header, 0, header.Length) != header.Length) return ImageType.UNKNOWN; //BMP string bmpHeader = Encoding.ASCII.GetString(header, 0, 2); if (bmpHeader == "BM")// window 平台下BMP图片标识,OS/2下图片标识可能为BA,CI,IC等 return ImageType.BMP; else if (bmpHeader == "BA") //BA= Bitmap array return ImageType.BMP; else if (bmpHeader == "CI") //CI= Color Icon return ImageType.BMP; else if (bmpHeader == "CP") //CP= Color Pointer return ImageType.BMP; else if (bmpHeader == "IC") //IC= Icon return ImageType.BMP; else if (bmpHeader == "PT") //PI= Pointer return ImageType.BMP; //TIFF string tiffHeader = Encoding.ASCII.GetString(header, 0, 4); if (tiffHeader == "MM\x00\x2a") //大端模式下,TIFF前4个字节数据 return ImageType.TIFF; else if (tiffHeader == "II\x2a\x00") // 小端模式下,TIFF前4个字节数据 return ImageType.TIFF; //PNG if (header[0] == 0x89 && header[1] == 0x50 && header[2] == 0x4E && header[3] == 0x47 && header[4] == 0x0D && header[5] == 0x0A && header[6] == 0x1A && header[7] == 0x0A) return ImageType.PNG; // GIF string gifHeader = Encoding.ASCII.GetString(header, 0, 4); if (gifHeader == "GIF8") return ImageType.GIF; // JPEG if (header[0] == 0xFF && header[1] == 0xD8) return ImageType.JPG; // WMF if (header[0] == 0xD7 && header[1] == 0xCD && header[2] == 0xC6 && header[3] == 0x9A) return ImageType.WMF; // EMF if (header[0] == 0x01 && header[1] == 0x00 && header[2] == 0x00 && header[3] == 0x00) return ImageType.EMF; // Windows Icons if (header[0] == 0x00 && header[1] == 0x00 && header[2] == 0x01 && header[3] == 0x00) // ICO return ImageType.ICON; else if (header[0] == 0x00 && header[1] == 0x00 && header[2] == 0x02 && header[3] == 0x00) // CUR return ImageType.ICON; return ImageType.UNKNOWN; } /// <summary> /// 判断图片文件类型,通过指定的图片路径 /// ps:判断结果最终由文件后缀和文件头前8个字节决定 /// </summary> /// <param name="file"></param> /// <returns></returns> public static ImageType GetImageType(string file) { if (!System.IO.File.Exists(file)) return ImageType.UNKNOWN; //先验证文件的后缀,如果文件后缀为图片格式那么再通过对文件头前几个字节进行验证 //最后确定图片的格式 string fileExtension = Path.GetExtension(file).ToUpper(); if (IMAGE_EXTENSIONS.Contains(fileExtension)) { using (System.IO.Stream read = new FileStream(file, FileMode.Open, FileAccess.Read)) { return GetImageType((Stream)read); } } return ImageType.UNKNOWN; } #endregion #region 视频 public static VideoType GetVideoType(Stream stream) { byte[] header = new byte[16]; stream.Seek(0, SeekOrigin.Begin); if (stream.Read(header, 0, header.Length) != header.Length) return VideoType.UNKNOWN; //QuickTime,从第4字节开始判断6D , 6F,6F,76 ,对应ascii:....moov if (header[4] == 0x6d && header[5] == 0x6f && header[6] == 0x6f && header[7] == 0x76) return VideoType.QUICKTIME; //RM,需要判断扩张情况,RM V10 和扩展对应的文件头MagicNumber的ASCII:.RMF //string strflags = System.Text.Encoding.ASCII.GetString(header,0,4/9); if (header[0] == 0x2e && header[1] == 0x52 && header[2] == 0x4d && header[3] == 0x46) return VideoType.RMVB; else if (header[0] == 0x2e && header[1] == 0x52 && header[2] == 0x4d && header[3] == 0x46 && header[4] == 0x00 && header[5] == 0x00 && header[6] == 0x00 && header[7] == 0x12 && header[8] == 0x00) return VideoType.RMVB; //SWF ,magic number="46.57.53"(FWS) , 压缩后43 57 53 (CWS) if (header[0] == 0x46 || header[0] == 0x43) { if (header[1] == 0x57 && header[2] == 0x53) return VideoType.FLASH; } //FLV if (header[0] == 0x46 && header[1] == 0x4C && header[2] == 0x56) { return VideoType.FLASH; } //WMV if (header[0] == 0x30 && header[1] == 0x26 && header[2] == 0xb2 && header[3] == 0x75 && header[4] == 0x8e && header[5] == 0x66 && header[6] == 0xcf && header[7] == 0x11 && header[8] == 0xa6 && header[9] == 0xd9 && header[10] == 0x00 && header[11] == 0xAA && header[12] == 0x00 && header[13] == 0x62 && header[14] == 0xce && header[15] == 0x6c) return VideoType.WMV; //AVI,判断前4个字节和后8个字节 if (header[0] == 0x52 && header[1] == 0x49 && header[2] == 0x46 && header[3] == 0x46 && header[8] == 0x41 && header[9] == 0x56 && header[10] == 0x49 && header[11] == 0x20 && header[12] == 0x4C && header[13] == 0x49 && header[14] == 0x53 && header[15] == 0x54) return VideoType.AVI; return VideoType.UNKNOWN; } public static VideoType GetVideoType(string file) { if (!System.IO.File.Exists(file)) return VideoType.UNKNOWN; string fileextension = Path.GetExtension(file).ToUpper(); if (VIDEO_EXTENSION.Contains(fileextension)) { //mp4单独判断 if (fileextension.Equals(".mp4", StringComparison.CurrentCultureIgnoreCase)) return VideoType.MP4; using (System.IO.Stream read = new FileStream(file, FileMode.Open, FileAccess.Read)) { return GetVideoType((Stream)read); } } return VideoType.UNKNOWN; } #endregion #region 音频 public static AudioType GetAudioType(Stream stream) { byte[] header = new byte[16]; stream.Seek(0, SeekOrigin.Begin ); if (stream.Read(header, 0, header.Length) != header.Length) return AudioType.UNKNOWN; //Standard MIDI , 对应的ASCII:MThd ,不对 RMID格式做判断 if (header[0] == 0x4d && header[1] == 0x54 && header[2] == 0x68 && header[3] == 0x64) return AudioType.MID; //MP3 if (header[0] == 0xFF && header[1] == 0xFB && header[2] == 0x30) return AudioType.MP3; else if (header[0] == 0xFF && header[1] == 0xF3 && header[2] == 0x40) return AudioType.MP3; else if (header[0] == 0x49 && header[1] == 0x44) return AudioType.MP3; //WAV string strFlags = System.Text.Encoding.ASCII.GetString(header, 0, header.Length); //判断前4位和后7位(固定格式),中间为随机生成 bool flag1=strFlags.Substring(0,4).Equals("RIFF",StringComparison.CurrentCultureIgnoreCase); bool flag2=strFlags.Substring(strFlags.Length-8,7).Equals("WAVEfmt",StringComparison.CurrentCultureIgnoreCase); if(flag1&&flag2) //if (strFlags.Equals("RIFF....WAVEfmt", StringComparison.CurrentCultureIgnoreCase)) return AudioType.WAV; //WMA if (header[0] == 0x30 && header[1] == 0x26 && header[2] == 0xb2 && header[3] == 0x75 && header[4] == 0x8e && header[5] == 0x66 && header[6] == 0xcf && header[7] == 0x11 && header[8] == 0xa6 && header[9] == 0xd9 && header[10] == 0x00 && header[11] == 0xAA && header[12] == 0x00 && header[13] == 0x62 && header[14] == 0xce && header[15] == 0x6c) return AudioType.WMA; return AudioType.UNKNOWN; } public static AudioType GetAudioType(string file) { if (!System.IO.File.Exists(file)) return AudioType.UNKNOWN; string fileextension = Path.GetExtension(file).ToUpper(); if (AUDIO_EXTENSION.Contains(fileextension)) { using (System.IO.Stream read = new FileStream(file, FileMode.Open, FileAccess.Read)) { return GetAudioType((Stream)read); } } return AudioType.UNKNOWN; } #endregion /// <summary> /// 指定文件获取该文件的文件类型 /// </summary> /// <param name="file"></param> /// <returns></returns> public static ResourceType GetResourceType(string file) { if (GetImageType(file) != ImageType.UNKNOWN) return ResourceType.Image; if (GetAudioType(file) != AudioType.UNKNOWN) return ResourceType.Audio; if (GetVideoType(file) != VideoType.UNKNOWN) return ResourceType.Video; return ResourceType.Unknown; } /// <summary> /// 过滤文件 /// </summary> /// <param name="files"></param> /// <returns></returns> public static string[] FilterFile(string[] files) { List<string> lsFiles = new List<string>(); foreach (var file in files) { if (GetResourceType(file) != ResourceType.Unknown) lsFiles.Add(file); } return lsFiles.ToArray(); } /// <summary> /// 验证当前文件是否为系统支持的文件格式 /// </summary> /// <param name="file"></param> /// <returns></returns> public static bool IsSupportFileType(string file) { return GetResourceType(file) == ResourceType.Unknown ? false : true; } /// <summary> /// 判断文件是否为WMA文件 /// </summary> /// <param name="file"></param> /// <returns></returns> public static bool IsWMA(string file) { return GetAudioType(file) == AudioType.WMA ? true : false; } /// <summary> /// 判断文件是否为GIF文件 /// </summary> /// <param name="file"></param> /// <returns></returns> public static bool IsGif(string file) { return GetImageType(file) == ImageType.GIF ? true : false; } }