是否可以知道文件是否包含Unicode(每个字符16个字节)或8位ASCII内容?
答案 0 :(得分:8)
如果文件存在,可能能够阅读byte-order-mark。
答案 1 :(得分:3)
与Brian Agnew所说的关于阅读byte order mark的内容是一致的,这是一个特殊的两个字节,可能出现在文件的开头。
您还可以通过扫描文件中的每个字节并查看它们是否都小于128来了解它是否为ASCII。如果它们都小于128,那么它只是一个ASCII文件。如果其中一些超过128,那么还有一些其他编码。
答案 2 :(得分:3)
UTF-16字符都至少为16位,有些是32位,右前缀(0xE000到0xFFFF)。因此,只需扫描每个字符以查看是否少于128将无效。例如,两个字节0x20 0x20将以ASCII和UTF-8编码两个空格,但以UTF-16编码为单个字符0x2020(匕首)。如果已知文本是英语,偶尔有非ASCII字符,那么大多数其他每个字节都将为零。但是如果没有关于文本和/或它的编码的一些先验知识,就没有可靠的方法来区分一般的ASCII字符串和一般的UTF-16字符串。
答案 3 :(得分:2)
首先,ASCII是7位,所以如果任何字节的高位设置,你就知道该文件不是ASCII。
各种“常见”字符集,如ISO-8859-x,Windows-1252等,都是8位,所以如果每隔一个字节为0,你知道你正在处理只使用ISO-8859字符。
在尝试区分Unicode和某些编码(如UTF-8)时,您会遇到问题。在这种情况下,几乎每个字节都有一个值,因此您无法做出简单的决定。正如Pascal所说,您可以对内容进行某种统计分析:阿拉伯语和古希腊语可能不会在同一个文件中。但是,这可能比它的价值更多。
编辑以回应OP的评论:
我认为在您的内容中检查是否存在0值字节(ASCII NUL)就足够了,并根据它做出选择。原因是JavaScript关键字是ASCII,而ASCII是Unicode的子集。因此,这些关键字的任何Unicode表示形式都包含一个包含ASCII字符(低字节)的字节,另一个包含0(高字节)的字节。
我的一点需要注意的是,您仔细阅读文档以确保他们使用“Unicode”这个词是正确的(我查看了this page以了解该功能,但没有进一步了解。)
答案 4 :(得分:1)
如果您每次都需要解决此问题的文件足够长,并且某些想法它应该是什么(例如,unicode中的英文文本或ASCII中的英文文本) ,你可以对字符进行简单的频率分析,看看分布是否类似于ASCII或unicode。
答案 5 :(得分:1)
Unicode是字母表,而不是编码。你可能意味着UTF-16。有很多库(python-chardet立即想到)自动检测文本的编码,尽管它们都使用启发式。
答案 6 :(得分:1)
要以编程方式识别文件的类型(包括但不限于编码),最好的选择是使用libmagic。 BSD许可的它几乎是您将要遇到的每个Unix系统的一部分,但对于次要的系统,您可以将其与应用程序捆绑在一起。
例如,从C中检测mime类型很简单:
Magic = magic_open(MAGIC_MIME|MAGIC_ERROR);
mimetype = magic_buffer(Magic, buf, bufsize);
其他语言都有包装此库的自己的模块。
回到您的问题,这是我从file(1)
(libmagic(3)
的命令行界面)中得到的信息:
% file /tmp/*rdp
/tmp/meow.rdp: Little-endian UTF-16 Unicode text, with CRLF, CR line terminators
答案 7 :(得分:0)
对于您的具体用例,很容易辨别。只需扫描文件,如果发现任何NULL(“\ 0”),它必须是UTF-16。 JavaScript必须具有ASCII字符,它们由UTF-16中的前导0表示。