检测一个文件是否为文本文件/二进制文件的方法
2007-08-28 15:26
483 查看
判断一个文件是否为文本文件,最简单的方法是使用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的字符,或者值为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 比较的几个值,或者使用更有效的统计算法,希望本文对您有用!
相关文章推荐
- 检测一个文件是否存在的方法
- 判断文件是否文本文件还是二进制文件的两个有效方法
- 将多个文本文件合并成一个文件的3种方法
- NET检测文件和文件夹是否存在的方法
- 嵌入式 Linux下判断是否是一个目录还是一个文件的方法
- PHP检测文件方法,类方法是否存在
- 在程序中判断一个文件是否可读的方法
- 在config配置文件添加iis的Mime类型,检测文件中是否存在添加语句,使用xml解析方法
- [VB.NET]vb.net中如何检测一个已知的文件是否已经被打开或者被其他应用程序调用
- python 一个简单的依靠文件来判断key是否重复的方法
- C++中判断一个文件是否存在的方法
- configure文件中判断某函数或库是否存在的一个方法
- 将多个文本文件合并成一个文件的3种方法
- 考虑增加一个islogined方法,用来检测是否已经登录
- 自动化测试:k8s环境下,通过检测文件是否存在来自动启停tomcatapp的方法_20160316_七侠镇莫尛貝
- 驱动中确认文件是否存在的一个方法
- go语言检测文件是否存在的方法
- 原生如何检测变量是否是一个数组的几种方法
- java判断一个文件是否为二进制文件的方法
- 查看一个文件是否支持64位 方法 ,[symbol(s) not found for architecture x86_64]相关