2

I read about someone having troubles with BufferedReader: the reader simply do not read the first lines. I have instead the opposite problem. For example, in a text file with 300 lines, it arrives at 200, read it half of it and then the following string is given null, so it stops.

private void readerMethod(File fileList) throws IOException {
    BigInteger steps = BigInteger.ZERO;
    BufferedReader br = new BufferedReader(new FileReader(fileList)); 

    String st;
    //reading file line by line
    try{
        while (true){
            st = br.readLine();
            if(st == null){
                System.out.println("Null string at line " + steps);
                break;
            }
            System.out.println(steps + " - " + st);
            steps = steps.add(BigInteger.ONE);
        }
    }catch(Exception e){
        e.printStackTrace();
    }
    finally{
        try{
            br.close();
        }catch(Exception e){}
    }
}

The output of the previous slice of code is as expected until it reaches line 199 (starting from 0). Consider a file with 300 lines.

... 198 - 3B02D5D572B66A82F9D21EE809320DB3E250C6C9 199 - 6E2C69795CB712C27C4097119CE2C5765 Null string at line 200

Notice that, all lines have the same length, so in this output line 199 is not even complete. I checked the file text, and it's correct: it contains all 300 lines and they are all of the same length. Also, in the text there are only capitals letters and numbers, as you can see.

My question is: how can i fix this? I need that the BufferedReader read all the text, not just a part of it.

As someone asked i add here the remaining part of the code. Please notice that all capital names are constant of various type (int, string etc). This is the method that is called by the main thread:

public void init(){
    BufferedWriter bw = null;
    List<String> allLines = createRandomStringLines(LINES);
    try{
        String fileName = "SHA1_encode_text.txt";
        File logFile = new File(fileName);
        System.out.println(logFile.getCanonicalPath());
        bw = new BufferedWriter(new FileWriter(logFile));

        for(int i = 0; i < allLines.size(); i++){
            //write file
            String o = sha1FromString(allLines.get(i));
            //sha1FromString is a method that change the aspect of the string,
            //replacing char by char. Is not important at the moment.
            bw.write(o + "\n");
        }

    }catch(Exception e){
        e.printStackTrace();
    }finally{
        try{
            bw.close();
        }catch(Exception e){}
    }

}

The method that create the list of random string is the following. "SYMBOLS" is just a String contains all avaiable chars.

private List<String> createRandomStringLines(int i) {
    List<String> list = new ArrayList<String>();
    while(i!=0){
        StringBuilder builder = new StringBuilder();
        int count = 64;
        while (count-- != 0) {
            int character = (int)(Math.random()*SYMBOLS.length());
            builder.append(SYMBOLS.charAt(character));
        }
        String generatedString = builder.toString();
        list.add(generatedString);
        i--;
    }
    return list;
}

Note that, the file written is totally correct.

  • Hello. What is `LINES` in `BufferedReader br = new BufferedReader(new FileReader(fileList), LINES + 1);` ? – Mickael Nov 09 '18 at 09:12
  • Ah sorry, i forgot it. It is just the number of lines. There was a previous method were i created random strings, and LINES is just an int constant in order to create it more efficently. – Daniele Buonadonna Nov 09 '18 at 09:14
  • Why do you even declare a buffer size for the BufferedReader? Why don't you use the default one? Creating one with the size of 301 is really weird to me. – Amongalen Nov 09 '18 at 09:18
  • Please, tell us, what is the full content of line 199. – ygor Nov 09 '18 at 09:19
  • I do. I define the number of lines just to get a clearer output and because i will need it after. Also, the while loop should reach the of the file, independently of the number of line it is at the moment. I hope to have answered correctly to you question, hoping that i do not misunderstanded something. – Daniele Buonadonna Nov 09 '18 at 09:21
  • 1
    When you take a look at `BufferedReader` code, you can see that the size is the number of caracters and not the number of lines. I don't think this is the problem here but you should fix this. – Mickael Nov 09 '18 at 09:22
  • In order to reply to ygor. I runned the programm another few times, so the output has changed. At the moment, it is as follow: `198 - E2246565470462093EEFC83E5CCE46B0C9E07C67 199 - ED2AB7058F09C47E822AA5D0D5DFB7C9F Null string at line 200` full line 199 is ED2AB7058F09C47E822AA5D0D5DFB7C9F2DC96E3 – Daniele Buonadonna Nov 09 '18 at 09:25
  • Yes, thank you Mickael for the correction. But you were right, this doesn't concern the bigger problem. – Daniele Buonadonna Nov 09 '18 at 09:30
  • Can you further tell us, what operating system and file system you are using? Could you also share the file with us? – ygor Nov 09 '18 at 09:37
  • Have you tried to run it without declaring the buffer size at all? – Amongalen Nov 09 '18 at 09:39
  • I'm afraid not. The file is generated randomly at each running. I'm using window 10, but i don't understand what do you mean with "file system". – Daniele Buonadonna Nov 09 '18 at 09:40
  • Amongalen, yes i did. But nothing changes. As expected. – Daniele Buonadonna Nov 09 '18 at 09:41
  • 2
    Windows 10 is enough information. Please, show us the code, which generates the file. Do you close the writer properly ? Maybe the written file is not flushed properly before you attempt to read it. – ygor Nov 09 '18 at 09:41
  • Ok, i'm going to add the code, please wait few minutes. – Daniele Buonadonna Nov 09 '18 at 09:44
  • To get proper help post [mcve] (minimal - without unnecessary parts like GUI, but complete code example - so all we need is copy and paste it to our machines, to be able to run it and get same behavior/problem you are having). Your current example lacks part responsible for creating that 300 line file. – Pshemo Nov 09 '18 at 09:46
  • You can try using `Scanner` too: `Scanner scan = new Scanner(file); String line; while(scan.hasNextLine()) { line = scan.nextLine(); //... } scan.close();` – Sofo Gial Nov 09 '18 at 09:47
  • Have you tried: `java.nio.file.Files.lines(path)` that reads all lines from a file as a `Stream`? – anders Nov 09 '18 at 09:53
  • 1
    The method that reads the file by chance it running together with the method that writes it? Or does the reader start after the writer has finished? – Robert Kock Nov 09 '18 at 09:55
  • 1
    Please add "System.out.println("writer closed")" AFTER "bw.close();" and add "System.out.println("reader opening") BEFORE BufferedReader br = new BufferedReader(new FileReader(fileList)); In which order will those two messages appear ? – ygor Nov 09 '18 at 10:01
  • One more thing, please add e.printStackTrace() to catch(Exception e) AFTER bw.close(); – ygor Nov 09 '18 at 10:03
  • 1
    BufferedWriter's default buffer size is 8192. You reader stops reading exactly after 8192 bytes ((40+1)*199 + 33. It is almost certain, that your writer did only flush once. – ygor Nov 09 '18 at 10:07
  • Okay. Here we are, ygor got the point. The BufferedWriter close _after_ the BufferedReader start. I will see how to fix this issue. Thank you, everybody. I will let you know if something changes. – Daniele Buonadonna Nov 09 '18 at 10:48

1 Answers1

1

Okay, thanks to the user ygor, i manage to resolve it. The problem was that the BufferReader stars his job when the BufferWriter isn't closed yet. It was sufficient to move the command line that require the reader to work, after the bufferWriter.close() command.