首页 > 解决方案 > 有没有办法使用 java 查找文件编码类型(UTF-8 或 ANSI 或 Cp1252 或其他)

问题描述

我必须阅读一些 html 文件。如果我使用 UTF-8 作为字符集来读取和写入文件,则会在 html 页面中显示一些垃圾字符。看起来实际文件是 ANSI 编码的,因为我使用 UTF-8 来读取和写入文件,很少有空格显示为带有问号的黑色菱形。

有没有办法找到用于读/写特定文件的编码/字符集?

标签: javaencodingdetection

解决方案


不,这在数学上是不可能的。文件只是字节包,大多数编码使得任何字节都有意义。如果没有使用人工智能设置来分析您使用正确编码读取它的可能性(寻找混合来自不同 unicode 平面等的字符的单词),因此无法确定。

可以最终确定某些文件绝对不是 UTF_8(或者,被损坏),因为当您对某些字符进行 UTF-8 编码时,某些字节序列不会出现在字节流中。然而,这也不是很有用:你不能得出结论:哦!必须是 UTF-8!基于缺少这些无效序列。

你有一些选择

正确的方式

当您保存这些 HTML 文件时,即选择了编码(HTML 是从网络服务器接收并加载到浏览器内存中,并已使用 HTTP 响应标头“Content-Type”中列出的字符集从字节解码为字符,然后您要求浏览器将其保存到一个文件中,此时浏览器需要选择一种编码),或者它是已知的(用于保存 HTML 的工具会直接保存 HTML '原始',就像它发送过来一样) HTTP 连接,但作为此操作的一部分,此工具知道编码,因为 HTTP 服务器在“Content-Type”标头中发送它),因此是存储此信息或选择井的最佳时机已知编码(UTF-8 是个好主意)。

因此,请返回设法保存这些文件并从源头修复它的任何软件和/或进程:要么保存编码,要么确保 HTML 文件以 UTF-8 保存,无论您使用什么 HTTP 服务器这个 HTML 从发送它作为。

骇人听闻的方式

拿起放大镜,戴上你最好的帽子,戴上你的福尔摩斯。

通常的策略是打开一个十六进制编辑器并移动到文件中您看到菱形或意外字符的位置并查看字节序列。尤其是如果它是一个有点“众所周知”的西方非 ASCII 字符,例如 é 或 ö,那么很有可能在网络上搜索你看到的字节,通常你会找到它。寻找十进制值 128 或更高的那些,以十六进制,以 8、9 或字母开头的那些 - 因为下面的那些是 ASCII 并且几乎所有编码都以相同的方式编码,因此,对区分编码。

例如,如果您搜索0xE1 0xBA 0x9E第一个匹配项将您带到此页面,向下滚动到 0xe1 0xBA 0x9e 它会显示:这是代码点 1E9E 的 UTF-8 版本,即尖 s(ß - 德语中常见)。如果这在文本中有意义,我们就想通了。我们需要一个人工智能来进行文本分析,以确定它是否有意义。我没有,所以我们需要一个人工智能。换句话说,你的大脑必须完成这项工作。看看它:如果在替换 ß 后,文本显示Last Name: Boßler,您显然明白了 - Boßler 是德国姓氏,也是德国的一座山。如果您不确定,请再次进行网络搜索。

有时您必须弄清楚它应该是什么字符,并将其包含在搜索中。例如,如果您检查文件并看到 a0xDF并且您知道 ß 必须在那里,搜索0xDF ß并进入此页面,该页面显示大量编码以及它们如何存储 ß。只有少数将其存储为 0xDF:它是一些 ISO-8859 变体,或 Cp-125x 变体(又名 windows-125x),并且您已设法排除 IBM852。无法知道它实际上是哪个 ISO-8859 或 Cp-125 变体;您将需要更多奇怪的字符,并希望您找到一个知道它应该是什么的字符,并且这些字符之间的编码方式不同(不太可能;它们非常相似)。

很可能最终你会知道它是几种编码之一,因为通常有多种编码都会产生完全相同的字节序列。事实上,如果你有全 ASCII 字符,那么它可能有数千种编码。


推荐阅读