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

我有以下文本文件:

在此处输入图像描述

该文件使用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编码保存的,它可以正常工作。

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

这实际上不是一个空白字符,它是一个BOM – 字节顺序标记 。 Windows使用BOM将文件标记为unicode(UTF-8,UTF-16和UTF-32)编码文件。

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

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

您需要使用OutputStreamReader类作为BufferedReader的reader参数。 它确实接受编码。 查看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之间的操作 IGNORE | REPLACE | REPORT

例如,null字符。 当你使用(char)0时,被翻译成”

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

即使我试图使用s1.trim(); 它的长度仍然是5。

我希望你这样做:

  s1.trim(); 

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

  s1 = s1.trim(); 

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

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