检测一个文件是否为文本文件/二进制文件的方法

        判断一个文件是否为文本文件,最简单的方法是使用UE或者editplus之类的文本编辑器打开看看,如果没有明显的乱码且代码页正确,则可以判定是文本文件(多简单阿,有眼睛的都能看出来),但是如果需要程序判断的话怎么办呢?

        有几种方法可以考虑

一.      判断不可见字符 

         我们知道,一般文本文件中是不会带有除空白字符之外的控制符号的,我们可以检测是否存在这些字符来判断是否为文本文件,例如文本中出现值为0的字符,或者值为255的字符,很明显不是文本文件,但是如果是Unicode编码或者中文字符(特别是繁体中文)呢? 还是不太好办。。。

 

二.     检索字符码表

       既然控制字符无法完全解决该问题,那我们把常用编码的码表统计出来,找到码表中的有效区段,这样当文件中出现的所有字符都在这些区段范围时,该文件即可确定为文本文件了。

      但是这种方法太猥琐了,还是baidu一下,google一会吧

 

三.      统计不可见字符

       搜了一通后,发现有人说google有篇论文是采用统计不可见字符的方法实现的,不过没找到该文章所说的论文,所以自己随便实现了一下,结果表名有一些效果,统计的比率伐值控制好的话,应该是很实用很简单的一种办法。 在实验了一堆html文件之后信心大增,可是在接下来处理简单Unicode字符时却遇到了麻烦,这种文件中可能有N多的0。。。。。。

        怎么对付Unicode文件呢? 继续搜索!

        终于找到了识别Unicode的代码,用C#实现如下:

public bool CheckIsUniFile(byte[] header)
        {
            if (header.Length < 2)
                return false;

            bool flag = false;
            if ((header[0] == 0xfe) && (header[1] == 0xff))
            {
                // Unicode,bigEndian
                flag = true;
            }
            else if ((header[0] == 0xff) && (header[1] == 0xfe))
            {
                if (((header.Length >= 4) && (header[2] == 0)) && (header[3] == 0))
                {
                    //UTF32
                }
                else
                {
                    // UNICODE,littleEndian
                }
                flag = true;
            }
            else if (((header.Length >= 3) && (header[0] == 0xef)) && ((header[1] == 0xbb) && (header[2] == 0xbf)))
            {
                // UTF8
                flag = true;
            }
            else if ((((header.Length >= 4) && (header[0] == 0)) && ((header[1] == 0) && (header[2] == 0xfe))) && (header[3] == 0xff))
            {
                //UTF32,bigEndian
                flag = true;
            }

            return flag;

            //throw new System.NotImplementedException();
        }

       该函数需要传入2到4个字节的文件头标识,用来识别是否为Unicode文件的标志。

       那么判定文件为文本文件的代码也比较好写了,代码为c#的实现:

/// <param name="strFilename">文件名</param>
        public bool CheckIsTxtFile(string strFilename)
        {
            if (!File.Exists(strFilename))
                return false;

            int[] naCharVisible = new int[2]; // 可见字符统计表,[0] 表示可见个数,[1]表示不可见个数
            byte[] header = new byte[4];

            FileStream fs = File.OpenRead(strFilename);
            byte[] buffer = new byte[1024];

            int nReadCount = fs.Read(buffer, 0, 1024);
            if (nReadCount >= 4)
            {
                header[0] = buffer[0];
                header[1] = buffer[1];
                header[2] = buffer[2];
                header[3] = buffer[3];
            }

            for (int i = 0; i < nReadCount; i++)
            {
                byte item = buffer[i];
                if (item < ' ')
                {
                    naCharVisible[1]++;
                    //return false;
                }
                else
                {
                    naCharVisible[0]++;
                }
            }

            if (fs.Length > 1024)
            {
                fs.Seek(-1024, SeekOrigin.End);
            }
            nReadCount = fs.Read(buffer, 0, 1024);

            for (int i = 0; i < nReadCount; i++)
            {
                byte item = buffer[i];
                if (item < ' ')
                {
                    naCharVisible[1]++;
                    //return false;
                }
                else
                {
                    naCharVisible[0]++;
                }
            }

            //throw new System.NotImplementedException();
            if (naCharVisible[0] != 0 && naCharVisible[1] != 0)
            {
                int nRate = naCharVisible[0] * 100 / (naCharVisible[0] + naCharVisible[1]);
                if ( nRate >= 93)
                {
                    return true;
                }
                else if (nRate >= 60)
                {
                    return CheckIsUniFile(header);
                }
                else
                {
                    return false;
                }
            }
            else if (naCharVisible[0] == 0)
            {
                return false;
            }
            else
            {
                return true;
            }
        }

     文章基本写完了,最后要说的是如果检验结果不够精确,试着修改上面与nRate 比较的几个值,或者使用更有效的统计算法,希望本文对您有用!

 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值