我有一个西班牙语文件,所以它有很多字符,如:
á é í ó ú ñ Ñ Á É Í Ó Ú
我必须阅读该文件,所以我这样做:
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;
当我读取令牌列表时,所有特殊字符都消失了,并被这种字符替换:
Ó = Ó
Ñ = Ñ
等等......
发生了什么事?我从未遇到过charsets的问题(我假设是charset问题)。是因为这台电脑吗?我能做什么?
任何额外的建议将不胜感激,我正在学习!谢谢!
答案 0 :(得分:4)
您需要指定相关的字符编码。
BufferedReader rEntrada = new BufferedReader(
new InputStreamReader(new FileInputStream(fr), "UTF-8"));
答案 1 :(得分:4)
发生了什么事?
建议使用UTF-8编码进行读写的答案应该可以解决您的问题。我的答案更多的是关于将来发生的事情以及如何诊断类似的问题。
首先是http://www.utf8-chartable.de处的UTF-8字符表。页面上有一个下拉菜单,可让您浏览Unicode的不同部分。您的一个问题字符是Ó
。检查图表显示,如果您的文件是以UTF-8编码的,则字符为U+00D3 LATIN CAPITAL LETTER O WITH ACUTE
,UTF-8序列为两个字节,十六进制c3 93
现在让我们检查http://en.wikipedia.org/wiki/ISO/IEC_8859-1处的ISO-8859-1字符集,因为这也是一个流行的字符集。然而,这是那些单字节字符集之一。每个有效字符由单个字节表示,与UTF-8不同,其中字符可以用1,2或3个字节表示。
请注意,C3处的字符看起来像Ã但93处没有字符。所以您的默认编码可能不是ISO-8859-1。
接下来,让我们在http://en.wikipedia.org/wiki/Windows-1252查看Windows 1252。这几乎与ISO-8859-1相同,但用一些有用的字符填充一些空格。我们有一场比赛。 Windows 1252中的序列C3 93正好是字符串Ó
这一切告诉我的是,您的文件是UTF-8编码的,但是您的Java环境配置了Windows 1252,因为它是默认编码。如果您修改代码以显式指定字符集(“UTF-8”)而不是使用默认值,则代码将不太可能在不同环境中失败。
请记住 - 这可能就像其他方式一样容易发生。如果您有一个主要是西班牙文本的文件,它可以很容易地成为ISO-8859-1或Windows 1252编码文件。在这种情况下,在您的机器上运行的代码可以正常运行并将其切换为“UTF-8”编码会创建一组不同的乱码。
这是您获得相互矛盾的建议的部分原因。不同的人根据他们的平台遇到了不同的不匹配,因此发现了不同的修复。
如果有疑问,我在emacs中读取文件并切换到hexl-mode,这样我就可以在文件中看到确切的二进制数据。我确信有更好,更现代的方法来做到这一点。
最后的想法 - 可能值得一读The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!
答案 2 :(得分:2)
您的默认编码错误。您可能需要阅读UTF8或latin1。请参阅此代码段以在流上设置编码。另请参阅Java, default encoding
public class Program {
public static void main(String... args) {
if (args.length != 2) {
return ;
}
try {
Reader reader = new InputStreamReader(
new FileInputStream(args[0]),"UTF-8");
BufferedReader fin = new BufferedReader(reader);
Writer writer = new OutputStreamWriter(
new FileOutputStream(args[1]), "UTF-8");
BufferedWriter fout = new BufferedWriter(writer);
String s;
while ((s=fin.readLine())!=null) {
fout.write(s);
fout.newLine();
}
//Remember to call close.
//calling close on a BufferedReader/BufferedWriter
// will automatically call close on its underlying stream
fin.close();
fout.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
答案 3 :(得分:2)
根据我的经验,文本文件应根据西方编码进行读写:ISO-8859-1。
BufferedReader rEntrada = new BufferedReader( new InputStreamReader(new FileInputStream(fr),“ISO-8859-1”));
答案 4 :(得分:0)
其他答案为您提供正确的方向。只是想添加Guava及其Files.newReader(File,Charset)辅助方法,使得创建这样的BufferedReader有很多可读性(请原谅双关语):
BufferedReader rEntrada = Files.newReader(new File(ficheroEntrada), Charsets.UTF_8);