7

是否可以知道文件是否具有 Unicode(每个字符 16 字节)或 8 位 ASCII 内容?

4

8 回答 8

9

如果文件存在此文件,您可能能够读取byte-order-mark 。

于 2009-11-21T14:36:21.860 回答
4

与 Brian Agnew 所说的读取字节顺序标记相同,这是一个特殊的两个字节,可能出现在文件的开头。

您还可以通过扫描文件中的每个字节并查看它们是否都小于128来知道它是否是ASCII。如果它们都小于128,那么它只是一个ASCII文件。如果其中一些超过 128,则其中有一些其他编码。

于 2009-11-23T06:54:26.667 回答
4

UTF-16 字符至少都是 16 位,有些是 32 位,带有正确的前缀(0xE000 到 0xFFFF)。因此,只需扫描每个字符,看看是否小于 128 就行不通。例如,两个字节 0x20 0x20 将以 ASCII 和 UTF-8 编码两个空格,但以 UTF-16 编码单个字符 0x2020(匕首)。如果知道文本是英文的,偶尔有非 ASCII 字符,那么大多数其他字节将为零。但是如果没有关于文本和/或其编码的先验知识,就没有可靠的方法来区分一般的 ASCII 字符串和一般的 UTF-16 字符串。

于 2016-03-23T21:36:53.810 回答
2

首先,ASCII 是 7 位的,所以如果任何字节设置了它的高位,您就知道该文件不是 ASCII。

各种“通用”字符集,例如 ISO-8859-x、Windows-1252 等,都是 8 位的,因此如果每隔一个字节为 0,您就知道您正在处理仅使用 ISO-8859 的 Unicode人物。

在尝试区分 Unicode 和某些编码(例如 UTF-8)时,您会遇到问题。在这种情况下,几乎每个字节都会有一个值,所以你不能轻易做出决定。正如 Pascal 所说,您可以对内容进行某种统计分析:阿拉伯语和古希腊语可能不在同一个文件中。然而,这可能比它的价值更多。


编辑以回应OP的评论:

认为检查内容中是否存在 0 值字节(ASCII NUL)就足够了,并据此做出选择。原因是 JavaScript 关键字是 ASCII,而 ASCII 是 Unicode 的子集。因此,这些关键字的任何 Unicode 表示将由一个包含 ASCII 字符(低字节)的字节和另一个包含 0(高字节)的字节组成。

我的一个警告是您仔细阅读文档以确保他们对“Unicode”一词的使用是正确的(我查看了此页面以了解该功能,没有进一步查看)。

于 2009-11-21T15:11:15.753 回答
1

如果每次你必须解决这个问题的文件都足够长,并且你知道它应该是什么(比如,unicode 中的英文文本或 ASCII 中的英文文本),你可以对chars 并查看分布是否类似于 ASCII 或 unicode。

于 2009-11-21T14:46:53.337 回答
1

Unicode 是字母表,而不是编码。您可能指的是 UTF-16。周围有很多库(立即想到 python-chardet)来自动检测文本的编码,尽管它们都使用启发式算法。

于 2009-11-21T14:52:10.193 回答
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
于 2018-08-28T16:50:47.787 回答
0

对于您的特定用例,很容易分辨。只需扫描文件,如果发现任何 NULL ("\0"),它必须是 UTF-16。JavaScript 必须有 ASCII 字符,它们由 UTF-16 中的前导 0 表示。

于 2009-11-21T17:25:14.343 回答