Java BufferedReader - 空行问题

时间:2015-06-09 23:25:30

标签: java file javafx line bufferedreader

问题描述:例如,我们有一个文本文件 file.txt ,内容如下:

Hello(LS)
what(LS)
are(LS)
<empty_line>(LS)
you(LS)
doing(LS)
<empty_line>(LS)
<empty_line>(LS)
now(LS)
<empty_line>(LS)
<empty_line>(LS)
<empty_line>(EOF)

(LS - 行分隔符,EOF - 文件结尾)

如果我理解了文本文件的想法,那么该文件就是这样的。现在,我想用这个文本填充示例TextArea(来自JavaFX)。我可以使用以下用try-catch包围的代码(close()方法将在finnaly块中):

TextArea textArea = new TextArea();
BufferedReader br = new BufferedReader(new FileReader(new File("file.txt")));
String line;
while ((line = br.readLine()) != null) {
       textArea.appendText(line);
       textArea.appendText("\n");
}

该代码有一个大问题 - 每当文本文件以 empty_line 结尾时,目标TextArea中还有一行。当在EOF之前包含 empty_line 的文件时,因此加载到TextArea是正常的。我尝试了很多方法,但每次都有一些问题。

为什么我选择了BufferedReader? 我选择了BufferedReader,因为我只想要一些可以逐行读取源文本文件的读者。我想要那个读者,因为文件分隔符和操作系统独立性。

我对它的期望是什么? 我正在等待我逐行读取文件,当我正在阅读时,我设置了自定义分隔符(独立于源文件行分隔符) - 例如LF(&#34; \ n&#34;)。我正在等待与可能的不同行分隔符完全相同的内容!当我写入某个文件时(我正在使用BufferedReader(对于从TextArea读取文本并设置依赖于用户操作系统的行分隔符(System.getProperty("line.separator"))),存在类似的行为。

我尝试了什么? 我尝试了很多方法来做到这一点。我也尝试在BufferedReader类中使用方法read()并将它的返回值与-1进行比较,这意味着EOF。但是,有一个问题,我想使用自定义文件分隔符,而且我没有时间编写一些解析器。

我的问题:如何使用自定义行分隔符向TextArea(或任何字符串)写入文件内容而不需要任何额外或更少的行?

*如您所见,我的英语不是很好,所以我希望您能理解我,谢谢。

3 个答案:

答案 0 :(得分:4)

您正在自己添加换行符。

while ((line = br.readLine()) != null) {
       textArea.appendText(line);
       textArea.appendText("\n");
}

while循环中的第二行添加下一行。每次执行该语句时,光标将转到下一行。 因此,当文件光标从文件中读取最后一行时,它会将其附加到textArea,然后用新行字符附加它。这就是为什么你最后得到额外的空白行。

if((line = br.readLine()) != null)
     textArea.appendText(line);
while ((line = br.readLine()) != null) {
       textArea.appendText("\n");
       textArea.appendText(line);
}

答案 1 :(得分:3)

正如讨论中所述,问题在于readLine()以下文件的行为方式相同:

File A: "Hello\n"
File B: "Hello"

1st readLine() --> "Hello"
2nd readLine() --> null

==> we cannot know if there was a '\n' after the last line or not

解决方案:使用其他方法读取字符,其中两个解释如下:

一次一个角色:

String readFile(String file) throws IOException {
    FileReader fr = new FileReader(new File(file));
    String s = "";
    int c;
    while ((c = fr.read()) >= 0) {
        s += (c == '\n' ? myCharOrString : (char)c;
    }
    return s;
}

缓冲:

String readFile(String file, int bufferSize) throws IOException {
    FileReader fr = new FileReader(new File(file));
    char[] buffer = new char[bufferSize];
    int charsRead;
    String s = "";
    while ((charsRead = fr.read(buffer)) > 0) {
        s += new String(buffer, 0, charsRead);
    }
    return s.replaceAll("\\r\\n?", "\n");
}

答案 2 :(得分:2)

奥基, 我做的!我不知道有多少是有效的,或者我可以使用不同的阅读器而不是BufferedReader,但这对我有用:

TextArea textArea = new TextArea();
String someString;
bufferedReader = new BufferedReader(new FileReader(file));

StringBuilder codeTextArea = new StringBuilder();
int character;
while ((character = bufferedReader.read()) != -1)
       codeTextArea.append((char) character);
//for TextArea you can use just toString and it set up separators to LF
this.textArea.setText(codeTextArea.toString());
//for String where you want line separator LF you can use for example following regex expression
someString = codeTextArea.toString().replaceAll("\r\n?","\n");

正如您在第二种情况中所看到的,我使用正则表达式来检测和替换行分隔符。该代码可以读取带有分隔符LF,CR,CRLF的文本文件并在TextArea中正确填充它(包括最后一个空行)或具有最低内存要求的String,因为一个字符(“\ n”) )对于行分离,也与TextArea默认行分隔符对应(它使用相同的 - LF)。

该代码可能不是很简单,但它可以工作。所以我问你是否知道如何简化它以获得最佳的硬件性能。