C#获取真实文件类型MIME,而不是通过文件扩展名

81 篇文章 3 订阅
13 篇文章 1 订阅

文件后缀名获取的可能是假的,比如 a.dll 可能是a.xml修改后缀扩展名来伪装的,本质上a.dll仍然是一个XML文件。

获取真实文件类型MIME。比如.rar强行修改扩展名后伪装成.jpg

经测试无法获取文本文件的真实类型【.txt,.csv,.log,.sql】

C#获取真实文件类型

新建窗体应用程序AutoGetFileTypeDemo,.net 4.5或以上版本,将默认的Form1重命名为FormGetActualFileType,添加对System.Web.dll的引用,窗体设计如图:

 窗体FormGetActualFileType主要代码如下(忽略设计器自动生成的代码):

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace AutoGetFileTypeDemo
{
    public partial class FormGetActualFileType : Form
    {
        public FormGetActualFileType()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 显示提示消息
        /// </summary>
        /// <param name="content"></param>
        private void DisplayMessage(string content)
        {
            if (rtxtMessage.TextLength >= 20480)
            {
                rtxtMessage.Clear();
            }
            rtxtMessage.AppendText($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")} -> {content}\n");
            rtxtMessage.ScrollToCaret();
        }

        private void btnSelectedFile_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Multiselect = false;
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                string fileName = openFileDialog.FileName;
                txtSelectedFile.Text = fileName;
                txtExtensionName.Text = Path.GetExtension(fileName);
                //添加System.Web.dll的引用
                string mimeType = System.Web.MimeMapping.GetMimeMapping(fileName);
                txtMimeType.Text = mimeType;
                string actualFileType = GetActualFileType(fileName);
                txtActualFileType.Text = actualFileType;
                DisplayMessage($"  文件【{Path.GetFileName(fileName)}】的MIME映射为【{mimeType}】");
                DisplayMessage($"  文件【{Path.GetFileName(fileName)}】的真实文件类型描述为【{actualFileType}】");
            }
        }

        /// <summary>
        /// 获取真实的文件类型MIME
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        private string GetActualFileType(string fileName)
        {
            FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read);
            BinaryReader binaryReader = new BinaryReader(fileStream, Encoding.Default);
            byte[] buffer = binaryReader.ReadBytes(4);
            binaryReader.Close();
            fileStream.Close();
            DisplayMessage($"文件【{fileName}】流的起始字节为【{string.Join(",", buffer)}】");
            //魔数映射
            string magicNumberMapping = string.Join("", buffer.Select(element => element.ToString("X2")));
            DisplayMessage($"文件【{fileName}】流的起始字节【十六进制】为【{magicNumberMapping}】");
            //File.AppendAllLines("D:\\abc.txt", new string[] { Path.GetExtension(fileName) + "|" + magicNumberMapping + "|" + string.Join(",", buffer) }, Encoding.Default);
            string actualMimeType = "unknown或文本文件";
            if (magicNumberMapping.StartsWith("D0CF"))
            {
                actualMimeType = "Word或Excel文件|.doc,.docx,.xls,.xlsx,.ppt,.pptx";
            }
            else if (magicNumberMapping.StartsWith("4D5A"))
            {
                actualMimeType = "dll或exe文件|.dll,.exe,.com,.msi";
            }
            else if (magicNumberMapping.StartsWith("25504446"))
            {
                actualMimeType = "pdf文件|.pdf";
            }
            else if (magicNumberMapping.StartsWith("52617221"))
            {
                actualMimeType = "rar压缩文件|.rar";
            }
            else if (magicNumberMapping.StartsWith("504B0304"))
            {
                actualMimeType = "zip压缩文件|.zip";
            }
            else if (magicNumberMapping.StartsWith("377ABCAF"))
            {
                actualMimeType = "7z压缩文件|.7z";
            }
            else if (magicNumberMapping.StartsWith("89504E47"))
            {
                actualMimeType = "png图片文件|.png";
            }
            else if (magicNumberMapping.StartsWith("FFD8FFE0"))
            {
                actualMimeType = "jpeg压缩图片文件|.jpg,.jpeg";
            }
            else if (magicNumberMapping.StartsWith("EFBBBF3C"))
            {
                actualMimeType = "xml文件|.xml";
            }
            else if (magicNumberMapping.StartsWith("00000100"))
            {
                actualMimeType = "ico图标文件|.ico";
            }
            else if (magicNumberMapping.StartsWith("47494638"))
            {
                actualMimeType = "gif动画文件|.gif";
            }
            else if (magicNumberMapping.StartsWith("424D"))
            {
                actualMimeType = "bmp位图文件|.bmp";
            }
            else if (magicNumberMapping.StartsWith("7B5C7274"))
            {
                actualMimeType = "rtf富文本格式文件|.rtf";
            }
            else if (magicNumberMapping.StartsWith("57415645"))
            {
                actualMimeType = "wav音频文件|.wav";
            }
            else if (magicNumberMapping.StartsWith("68746D6C"))
            {
                actualMimeType = "html网页文件|.html";
            }
            else if (magicNumberMapping.StartsWith("41564920"))
            {
                actualMimeType = "avi播放文件|.avi";
            }
            return actualMimeType;//不考虑文本文件.txt,.csv,.log,.sql等
        }
    }
}

/*
 * MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型。
 * 一般来说,某种类型的文件的起始几个字节都是固定的。
 * 根据这几个起始字节的内容就可以确定文件类型,因此这几个字节的内容被称为魔数 (magic number)。
 * 常用文件的文件头如下:(以前六位为准)
JPEG (jpg),文件头:FFD8FF 
PNG (png),文件头:89504E47 
GIF (gif),文件头:47494638 
TIFF (tif),文件头:49492A00 
Windows Bitmap (bmp),文件头:424D 
CAD (dwg),文件头:41433130 
Adobe Photoshop (psd),文件头:38425053 
Rich Text Format (rtf),文件头:7B5C727466 
XML (xml),文件头:3C3F786D6C 
HTML (html),文件头:68746D6C3E 
Email [thorough only] (eml),文件头:44656C69766572792D646174653A 
Outlook Express (dbx),文件头:CFAD12FEC5FD746F 
Outlook (pst),文件头:2142444E 
MS Word/Excel (xls.or.doc),文件头:D0CF11E0 
MS Access (mdb),文件头:5374616E64617264204A 
WordPerfect (wpd),文件头:FF575043 
Postscript (eps.or.ps),文件头:252150532D41646F6265 
Adobe Acrobat (pdf),文件头:255044462D312E 
Quicken (qdf),文件头:AC9EBD8F 
Windows Password (pwl),文件头:E3828596 
ZIP Archive (zip),文件头:504B0304 
RAR Archive (rar),文件头:52617221 
Wave (wav),文件头:57415645 
AVI (avi),文件头:41564920 
Real Audio (ram),文件头:2E7261FD 
Real Media (rm),文件头:2E524D46 
MPEG (mpg),文件头:000001BA 
MPEG (mpg),文件头:000001B3 
Quicktime (mov),文件头:6D6F6F76 
Windows Media (asf),文件头:3026B2758E66CF11 
MIDI (mid),文件头:4D546864 
*/

程序运行如图:

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

斯内科

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值