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

在Java中读取奇怪的unicode字符?,java,unicode,file-io,Java,Unicode,File Io,我有以下文本文件: 该文件以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 = "

我有以下文本文件:

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

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


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

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

例如,空字符。使用(char)0时,将被转换为“”

可能是filereader正在读取文件开头的空字符。我不知道为什么

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

我希望您正在这样做:

    s1.trim();
那不是你想要它做的。Java字符串是不可变的,
trim()
方法正在创建一个新字符串。。。然后你就把它扔掉了。您需要这样做:

    s1 = s1.trim();
。。。它将对
trim()
创建的新字符串的引用指定给某个对象,以便您可以使用它


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

那么,您可能正在尝试使用不同的编码读取文件

您需要使用
OutputStreamReader
类作为
BufferedReader
的读卡器参数。它确实接受编码。为它复习

有点像这样:

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

之间进行选择,您确定第一行末尾没有空格吗?否则,只需使用
String.trim
这是记事本中的一个bug。你应该报告它。但是我如何在Java中删除这样的字符呢?@ipkiss:if(s1.charAt(0)='\uFEFF')s1=s1.substring(1);这是一个众所周知的Windows错误。