我有以下文本文件:
该文件使用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编码保存的,它可以正常工作。
答案 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()
方法只是按原样返回它。)