3

I have a BufferedReader that's reading a file. The file can easily have an empty line between 2 paragraphs ex:

Lorem ipsum dolor sit amet, mel in docendi eleifend sapientem, mei cu natum possit salutandi. Quaeque legimus appareat cum in, tamquam cotidieque duo in. Justo ubique efficiantur ei sit, idque dicat sadipscing ad sit. Amet consul disputationi ei sea. At reque lorem quo, animal singulis per cu, usu euripidis reprimique inciderint eu.

Ocurreret dissentias ei per. Copiosae vulputate vel ei, ne est dissentias adversarium, ad quo graecis nostrum volutpat. Vix ut sale persequeris, id est volumus noluisse, mel et ridens molestiae. Ut qui iriure volutpat contentiones, unum propriae inciderint ut duo. Ei singulis delicata per. Usu verterem nominati in.

The BufferedReader stops reading when it reaches the end of the first paragraph. I know why it stops as it thinks as long as an empty line is found, it thinks it's the end of the file, which is my problem.

I've been using the while loop way to iterate through the file.

I've scrambled around this problem so much I scrapped my original bufferedreader method and editted it a lot of times, but it was something like: (pseudo code, this code is not correct. notice the while loop mainly)

public static String currenttxt() throws IOException {
   BufferedReader br = new BufferedReader(new FileReader(file)); 
     try {
        while (br.readLine() != null) {
           return br.readline();
        }
     } catch (Exception e) {
        e.PrintStackTrace();
     }
}

How can I solve this issue?

Saad Ardati
  • 379
  • 6
  • 17
  • Can you update your question with relevant code snippet. – Nayan Wadekar Dec 05 '14 at 09:17
  • Will do. Give me a minute. – Saad Ardati Dec 05 '14 at 09:22
  • 1
    You read twice from the stream. The data that you read inside the while() is discarded :( – f1sh Dec 05 '14 at 09:32
  • 1
    Your function will only ever return first line of the file because of the `return` in the loop. The loop will never be executed more than once. I would guess your first "paragraph" is a really a single "line". –  Dec 05 '14 at 09:32

2 Answers2

1

You should initialize a varible and assign it a value every time you reading a line to avoid the problem:

    BufferedReader br = new BufferedReader(new FileReader(file));
    StringBuilder sb = new StringBuilder();
    String line = br.readLine();

    while (line != null) {
        sb.append(line);
        line = br.readLine();
    }

    return sb.toString();

If you want to preserve the empty line between paragraphs it is better to read per char:

    BufferedReader br = new BufferedReader(new FileReader(file));
    StringBuilder sb = new StringBuilder();
    int c = br.read();

    while (c != -1) {
        sb.append(String.valueOf((char)c));
        c = br.read();
    }

    return sb.toString();
specializt
  • 1,913
  • 15
  • 26
Yevgen
  • 1,576
  • 1
  • 15
  • 17
  • 1
    using assignments inside of loop-heads is absolutely error-prone and pretty much what people would call "bad code". – specializt Dec 05 '14 at 09:53
  • 1
    @specializt Not closing resources is also considered as bad practice and error-prone. To show how to implement it "correctly" it's ok to use an assignment within the loop - just my two cents. – andih Dec 05 '14 at 10:13
  • you obviously dont know how Java works. Resources close themselves automatically, explicitly controlling that behaviour is only reasonable once external resources depend on it, in every other case simply discarding the object does everything like its supposed to happen (in this case). This isnt C. – specializt Dec 05 '14 at 10:34
  • @specializt there is a lot of discussion about this topic one can be found here http://stackoverflow.com/questions/515975/closing-streams-in-java – andih Dec 05 '14 at 10:46
  • thats nice .... and always remember : java does most of the "cleaning" for you - its called "garbage collection" although one should not rely on it everytime. – specializt Dec 05 '14 at 10:51
  • It compresses the entire text into one paragraph rather than preserving the empty lines. :/ – Saad Ardati Dec 05 '14 at 11:07
  • @user3262990 The BufferedReader preserve empty lines. – andih Dec 05 '14 at 11:41
  • @SaadArdati have a look at my answer, there is a `b.append(System.getProperty("line.separator"));` missing. – andih Dec 05 '14 at 11:44
  • @andih, take a look — https://docs.oracle.com/javase/7/docs/api/java/io/BufferedReader.html#readLine() – Yevgen Dec 05 '14 at 11:55
  • @user3262990 The JavaDoc describes how a line is line limited. It does not say that empty lines are removed. The BufferedReader should not remove empty lines - see also [Buffered Reader readLine() with Empty lines](http://stackoverflow.com/questions/3527108/buffered-reader-readline-with-empty-lines) – andih Dec 05 '14 at 13:40
  • No lines are removed by readLine() method. But there is no line in simple '\n' expression, only line-separator alone. So in that case you need to read file per char or to add line-separator by hand like you did in your answer. – Yevgen Dec 05 '14 at 15:19
  • Nobody is talking about C here, this question is about **Java** - Java closes resources automatically, **if possible**, i recommend doing a bit of research about *"garbage collection"*, the modern version of the shipped GC is pretty powerful - it is certainly **not recommended** to discard resources without closing them but it [is possible](https://stackoverflow.com/a/18510092/351861) – specializt Jun 27 '17 at 08:42
1

As in the comments already mentioned your function is discarding the first line because of the while (br.readLine()) and leave the loop after reading the second line.

You should keep the line already read within some local variable.

public static String currenttxt() throws IOException {

       try (BufferedReader br = new BufferedReader(new FileReader(file))) {
       StringBuilder b = new StringBuilder();
         try {

            String line = br.readLine();
            while (line != null) {
               b.append(line);
               b.append(System.getProperty("line.separator"));
               line = br.readLine();
            }

         } catch (Exception e) {
            e.printStackTrace();
            throw e;
         }

         // remove the last line separator at the end using trim()
         return b.toString().trim();
       }

With java 7 it could be simplified to

public static String currenttxt() throws IOException{
    List<String> lines; 
    lines = Files.readAllLines(FileSystems.getDefault()
             .getPath(file.getAbsolutePath()));

    StringBuilder b = new StringBuilder();
    boolean insertNewLine = false;
    for (String line : lines) {
        if (insertNewLine) 
            b.append(System.getProperty("line.separator"));

        b.append(line);
        insertNewLine = true;       
    }

    return b.toString();
}

The second example shows one way how a trim() at the end could be avoided. Another way would be to remove the last line separator from the StringBuilder b.

andih
  • 5,570
  • 3
  • 26
  • 36