在Java中读取奇怪的unicode字符?

时间:2012-03-27 11:54:22

标签: java unicode file-io

我有以下文本文件:

enter image description here

该文件使用utf-8编码保存。

我使用以下代码来读取文件的内容:

FileReader fr = new FileReader("f.txt");
BufferedReader br = new BufferedReader(fr);
String s1 = br.readLine();
String s2 = br.readLine();
System.out.println("s1 = " + s1.length());
System.out.println("s2 = " + s2.length());

输出:

s1 = 5

s2 = 4

然后我尝试使用s1.charAt(0);来获取s1的第一个字符,它是''(空白)字符。这就是为什么s1的长度为5.即使我尝试使用s1.trim();,它的长度仍为5。 我不知道为什么会这样?如果文件是用ASCII编码保存的,它可以正常工作。

5 个答案:

答案 0 :(得分:7)

记事本显然用byte order mark保存了文件,一个非打印字符在开头只标记为UTF-8但不需要(实际上不推荐)使用。你可以忽略或删除它;其他文本编辑器通常会让您选择使用带或不带BOM的UTF-8。

答案 1 :(得分:1)

这实际上不是空白字符,而是BOM - Byte Order Mark。 Windows使用BOM将文件标记为unicode(UTF-8,UTF-16和UTF-32)编码文件。

认为即使在记事本中也可以保存没有BOM的文件(实际上并不需要)。

答案 2 :(得分:1)

好吧,您可能尝试使用不同的编码来阅读文件。

您需要使用OutputStreamReader类作为BufferedReader的阅读器参数。它确实接受编码。请查看Java Docs

有点像这样:

BufeferedReader out = new BufferedReader(new OutputStreamReader(new FileInputStream("jedis.txt),"UTF-8")))

或者您可以使用系统属性file.encoding将当前系统编码设置为UTF-8。

java -Dfile.encoding=UTF-8 com.jediacademy.Runner arg1 arg2 ...

如果您只需要这个特定文件,也可以在运行时使用System.setProperty(...)将其设置为系统属性,但在这种情况下,我认为我更喜欢OutputStreamWriter

通过设置系统属性,您可以使用FileReader并期望它将使用UTF-8作为文件的默认编码。在这种情况下,您读取和写入的所有文件。

如果您打算在文件中检测解码错误,您将被迫使用OutputStreamReader方法并使用接收解码器的构造函数。

有点像

CharsetDecoder decoder = Charset.forName("UTF-8").newDecoder();
decoder.onMalformedInput(CodingErrorAction.REPORT);
decoder.onUnmappableCharacter(CodingErrorAction.REPORT);
BufeferedReader out = new BufferedReader(new InputStreamReader(new FileInputStream("jedis.txt),decoder));

您可以选择操作IGNORE | REPLACE | REPORT

答案 3 :(得分:0)

例如,

空字符。当你使用(char)0时,被翻译成''

可能是文件读取器正在读取文件开头的空字符。我不确定为什么......

答案 4 :(得分:0)

  

即使我尝试使用s1.trim();它的长度仍为5.

我希望你这样做:

    s1.trim();

这不符合你的意愿。 Java字符串是不可变的,trim()方法正在创建一个新的String ...然后你就扔掉了。你需要这样做:

    s1 = s1.trim();

...将trim()创建的新String的引用分配给某些东西,以便您可以使用它。

(注意:trim()并不总是创建一个新的String。如果原始字符串没有前导空格或尾随空格,trim()方法只是按原样返回它。)