Java的字符集/字符编码

coc*_*nut 3 java character-encoding non-ascii-characters

我有一个西班牙语文件,所以充满了像这样的字符:

 á é í ó ú ñ Ñ Á É Í Ó Ú 
Run Code Online (Sandbox Code Playgroud)

我必须阅读文件,所以我这样做:

fr = new FileReader(ficheroEntrada);
BufferedReader rEntrada = new BufferedReader(fr);

String linea = rEntrada.readLine();
if (linea == null) {
logger.error("ERROR: Empty file.");
return null;
} 
String delimitador = "[;]";
String[] tokens = null;

List<String> token = new ArrayList<String>();
while ((linea = rEntrada.readLine()) != null) {
    // Some parsing specific to my file. 
    tokens = linea.split(delimitador);
    token.add(tokens[0]);
    token.add(tokens[1]);
}
logger.info("List of tokens: " + token);
return token;
Run Code Online (Sandbox Code Playgroud)

当我阅读令牌列表时,所有特殊字符都消失了,并已被此类字符替换:

Ó = Ó
Ñ = Ñ
Run Code Online (Sandbox Code Playgroud)

等等...

发生了什么?我从未遇到过字符集问题(我假设这是一个字符集问题)。是因为这台计算机吗?我能做什么?

任何额外的建议将不胜感激,我正在学习!谢谢!

kos*_*osa 5

您需要指定相关的字符编码。

BufferedReader rEntrada  = new BufferedReader(
    new InputStreamReader(new FileInputStream(fr), "UTF-8"));
Run Code Online (Sandbox Code Playgroud)


Gui*_*one 5

\n

发生了什么?

\n
\n\n

建议使用 UTF-8 编码进行读写的答案应该可以解决您的问题。我的回答更多的是关于发生了什么以及将来如何诊断类似的问题。

\n\n

第一个起点是http://www.utf8-chartable.de上的 UTF-8 字符表。页面上有一个下拉菜单,可让您浏览 Unicode 的不同部分。你的问题角色之一是\xc3\x93。检查图表显示,如果您的文件是用 UTF-8 编码的,那么字符就是U+00D3 LATIN CAPITAL LETTER O WITH ACUTEUTF-8 序列是两个字节,十六进制 c3 93

\n\n

现在让我们在http://en.wikipedia.org/wiki/ISO/IEC_8859-1检查 ISO-8859-1 字符集,因为这也是一个流行的字符集。然而,这是单字节字符集之一。每个有效字符都由一个字节表示,这与 UTF-8 不同,在 UTF-8 中,一个字符可能由 1、2 或 3 个字节表示。

\n\n

请注意,C3 处的字符看起来像 \xc3\x83,但 93 处没有字符。因此您的默认编码可能不是 ISO-8859-1。

\n\n

接下来让我们在http://en.wikipedia.org/wiki/Windows-1252上检查 Windows 1252 。这与 ISO-8859-1 几乎相同,但用有用的字符填充了一些空格。我们有一场比赛。Windows 1252中的序列C3 93正是该字符串\xc3\x83\xe2\x80\x9c

\n\n

这一切告诉我的是,您的文件是 UTF-8 编码的,但是您的 Java 环境配置为 Windows 1252 作为默认编码。如果您修改代码以显式指定字符集(“UTF-8”)而不是使用默认字符集,您的代码在不同环境下失败的可能性会降低。

\n\n

但请记住 - 这也可能很容易以其他方式发生。如果您有一个主要包含西班牙语文本的文件,它也可以很容易是 ISO-8859-1 或 Windows 1252 编码文件。在这种情况下,您的计算机上运行的代码本来可以正常工作,并且将其切换为读取“UTF-8”编码会创建一组不同的乱码。

\n\n

这是您收到相互矛盾的建议的部分原因。不同的人根据他们的平台遇到了不同的不匹配,因此发现了不同的修复方法。

\n\n

如有疑问,我在 emacs 中读取文件并切换到 hexl 模式,这样我就可以看到文件中确切的二进制数据。我确信有更好、更现代的方法可以做到这一点。

\n\n

最后一个想法 - 可能值得阅读《每个软件开发人员绝对必须了解 Unicode 和字符集的绝对最低要求》(没有借口!

\n