Java BufferedReader - empty string problem

Description of the problem: For example, we have a text file file.txt with the following content:

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)

      

(separator LS - lines, EOF - end of file)

If I got the idea of โ€‹โ€‹a text file, the file looks something like this. Now I want to fill for example TextArea (from JavaFX) with this text. I can use the following code surrounded by a try-catch method (the close () method will be in the final block):

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");
}

      

This code has one big problem - every time there is another line in the target TextArea where the text file does not end with an empty_line. When a file that contains an empty line before EOF is loaded into the TextArea. I tried a lot on how to do this, but there were some problems every time.

Why did I choose BufferedReader? I chose BufferedReader because I just want some reader to be able to read the original text file line by line. I want this reader, because of the file separator and OS independence.

What do I expect from this? I expect to read the file line by line, and when I read, I set up custom delimiters (regardless of the original file line delimiters) - like LF ("\ n"). And I expect exactly the same content with possible different line separators! When I write to some file (where I also use BufferedReader

) (for the trainee reading text from the TextArea and setting the line separators depends on the user OS ( System.getProperty("line.separator")

)), there is a similar behavior.

What have I tried? I've tried many ways how to do this. I have also tried using the read () method in the BufferedReader class and compare its return value with -1 which means EOF. BUT, there is one problem, I want to use custom file separators and I have no time to write some parsers.

My question is: How can I write in the TextArea (or any line) the contents of a file using specialized line separators without an extra or less line?

* As you can see, my English is not very good, so I hope you can understand me, thanks.

+3


source to share


3 answers


As it turned out in the discussion, the problem is that with the readLine()

following files will behave the same:

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

      

Solution: use other methods to read characters, two of which are described here:

One character at a time:



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;
}

      

buffering:

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");
}

      

+3


source


You add the new line yourself.

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

      



The second line in the while-loop adds the following line. Each time this statement is executed, the cursor moves to the next line. So when the file pointer reads the last line from the file, it adds it to the textArea and then adds it with a new line character. This is why you get an extra blank line at the end.

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

      

+4


source


Okay, I did it! I don't know how efficient this is, or if I can use a different Reader than the BufferedReader, but this works for me:

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");

      

As you can see in the second case, I am using a regexp to detect and replace line separators. This code can read LF, CR, CRLF delimited text files and correctly fill it (includes the last blank line ) in the TextArea or String with the least memory requirement due to one character ("\ n") for a single line, and also matches the default line separator TextArea (it uses the same - LF).

This code is probably not very simplistic, but it works. So I ask you if you know how to simplify it for the best hardware performance.

+2


source







All Articles