如何将文件内容标识为ASCII或二进制

时间:2008-11-10 10:20:22

标签: c++ ascii binaryfiles file-format

如何使用C ++将文件内容标识为ASCII或二进制文件?

11 个答案:

答案 0 :(得分:51)

如果文件包含十进制字节9-13,32-126,则它可能是纯ASCII文本文件。否则,事实并非如此。但是,它可能仍然是另一种编码的文本。

如果在添加上面的字节,该文件只包含 十进制字节128-255,它可能是一个8位或变量的文本文件 - 长度基于ASCII的编码,如ISO-8859-1,UTF-8或ASCII + Big5。如果没有,出于某些目的,您可以在此处停止并将文件视为二进制文件。但是,它可能仍然是16位或32位编码的文本。

如果文件不符合上述约束,请检查byte-order mark文件的前2-4个字节:

  • 如果前两个字节是十六进制FE FF,则文件暂定 UTF-16 BE。
  • 如果前两个字节是十六进制FF FE,并且以下两个字节十六进制00 00,则该文件暂时 UTF- 16 LE。
  • 如果前四个字节是十六进制00 00 FE FF,则文件暂定 UTF-32 BE。
  • 如果前四个字节是十六进制FF FE 00 00,则文件暂定 UTF-32 LE。

如果通过上述检查确定了暂定编码,则只检查下面的相应编码,以确保该文件不是符合字节顺序标记的二进制文件。

如果您尚未确定暂定编码,则该文件可能仍为其中一种编码的文本文件,因为字节顺序标记不是必需的,因此请检查以下列表中的所有编码:

  • 如果文件包含大端双字节字,其小数值为9-13,32-126和128或更高,则该文件可能是UTF-16 BE。
  • 如果文件包含小端双字节字,其小数值为9-13,32-126和128或更高,则该文件可能是UTF-16 LE。
  • 如果文件包含大端四字节字,其小数值为9-13,32-126和128或更高,则该文件可能是UTF-32 BE。
  • 如果文件包含小端四字节字,小数值为9-13,32-126和128或更高,则该文件可能是UTF-32 LE。

如果在所有这些检查之后,您仍未确定编码,则该文件不是我所知道的任何基于ASCII编码的文本文件,因此对于大多数用途,您可能认为它是二进制的(它可能仍然是非ASCII编码的文本文件,例如EBCDIC,但我怀疑这超出了您关注的范围。)

答案 1 :(得分:15)

使用带有stream.get()的普通循环遍历它,并检查您读取的字节值是否为<= 127。许多方法的一种方法:

int c;
std::ifstream a("file.txt");
while((c = a.get()) != EOF && c <= 127) 
    ;
if(c == EOF) {
    /* file is all ASCII */
}

然而,正如有人提到的,毕竟所有文件都是二进制文件。此外,还不清楚“ascii”的含义。如果你的意思是字符代码,那么这就是你的方式。但如果你的意思是只有字母数字值,你需要另一种方法。

答案 2 :(得分:11)

我的文本编辑器决定是否存在空字节。在实践中,这非常有效:没有空字节的二进制文件非常罕见。

答案 3 :(得分:10)

了解file command的工作原理;它有三种策略来确定文件的类型:

根据您的平台以及您感兴趣的可能文件,您可以查看其实现,甚至可以调用它。

答案 4 :(得分:8)

每个文件的内容都是二进制文件。所以,不知道什么,你不能确定。

ASCII是一个解释问题。如果您在文本编辑器中打开二进制文件,您会看到我的意思。

大多数二进制文件包含您可以查找的固定标头(每种类型),或者您可以将文件扩展名作为提示。如果您希望使用UTF编码的文件,可以查找字节顺序标记,但它们也是可选的。

除非您更仔细地定义您的问题,否则无法给出明确的答案。

答案 5 :(得分:7)

如果问题确实是如何只检测ASCII,那么litb的答案是正确的。但是,如果san在知道如何确定文件是否包含文本之后,则问题变得更加复杂。 ASCII只是一种 - 越来越不受欢迎 - 表示文本的方式。 Unicode系统 - UTF16,UTF32和UTF8越来越受欢迎。理论上,通过检查前两个字节是否是单字节字节顺序标记(BOM)0xFEFF(或者如果字节顺序颠倒则为0xFFFE),可以很容易地测试它们。然而,由于这两个字节搞砸了Linux系统的许多文件格式,因此不能保证它们存在。此外,二进制文件可能以0xFEFF开头。

如果文件是unicode,则查找0x00(或其他控制字符)也无济于事。如果文件是UFT16说,并且该文件包含英文文本,则每隔一个字符将为0x00。

如果您知道将写入文本文件的语言,则可以分析字节并统计确定它是否包含文本。例如,英语中最常见的字母是E,后跟T.因此,如果文件中包含的E和T比Z和X更多,则可能是文本。当然,有必要将其作为ASCII和各种unicodes进行测试以确保。

如果文件不是用英文写的 - 或者你想支持多种语言 - 那么剩下的两个选项就是在Windows上查看文件扩展名并检查“魔法文件”数据库的前四个字节“用于确定文件类型的代码,以及它是否包含文本。

答案 6 :(得分:1)

嗯,这取决于您对ASCII的定义。您可以使用ASCII代码<128来检查值,也可以检查您定义的某些字符集(例如'a' - 'z','A' - 'Z','0' - '9'......)并对待如果文件包含其他一些字符,则为二进制文件。

您还可以检查常规换行符(0x10或0x13,0x10)以检测文本文件。

答案 7 :(得分:1)

要检查,您必须将文件打开为二进制文件。您无法以文本形式打开文件。 ASCII实际上是二进制的子集。 之后,您必须检查字节值。 ASCII的字节值为0-127,但0-31是控制字符。 TAB,CR和LF是唯一常见的控制字符。 你不能(便携地)使用'A'和'Z';这些都不能保证是ASCII(!)。 如果您需要它们,则必须定义。

const unsigned char ASCII_A = 0x41; // NOT 'A'
const unsigned char ASCII_Z = ASCII_A + 25;

答案 8 :(得分:1)

这个问题确实没有正确或错误的答案,只是复杂的解决方案不适用于所有可能的文本文件。

这是a The Old New Thing Article关于记事本如何检测ascii文件类型的链接。它并不完美,但看看微软如何处理它会很有趣。

答案 9 :(得分:0)

Github's linuguist使用charlock holmes来检测二进制文件,而二进制文件又使用ICU&#39; charset detection

ICU库可用于许多编程语言,包括C和Java。

答案 10 :(得分:-2)

.catch()