在Java中读取奇怪的unicode字符?
我有以下文本文件: 该文件以utf-8编码保存 我使用以下代码读取文件的内容:在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 = "
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错误。