Search code examples
javabinarybufferedreaderfileinputstreamend-of-line

readline ignores \n or \r in files (text vs binary)


I have a knot in my thinking ... i am writing the int 0 to a file three times, each followed by a end of line designator (i have tried \n (0x0A) and \r (0x0D)). here is the content of the file in bytes

00 00 00 00 0D 00 00 00 00 0D 00 00 00 00 0D

to read it back in, i wrap a

FileInputStream is = new FileInputStream(theFile);
BufferedReader br = new BufferedReader(new InputStreamReader(is));

however, my first call to

String s = br.readLine();

reads to the end of the file (position 15) rather than stopping at position 5 (i.e. 0x0D) as i would have hoped. anyone see where i am misunderstanding how things work? much obliged.

Added info based on comment below: the code is

public class TestApp4 {
  public static void main(String args[]) {
    try {
        File theFile = new File("Test.dat");
        FileInputStream is = new FileInputStream(theFile);
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        System.out.println("input stream position: " + is.getChannel().position());
        String s = br.readLine();
        byte[] bs = s.getBytes();
        int i = ByteBuffer.wrap(bs).getInt();
        System.out.println("input stream position: " + is.getChannel().position());
        System.out.println("line: " + i);
        s = br.readLine();
        System.out.println("line: ");
        s = br.readLine();
        System.out.println("line: ");
        br.close();
    } catch (Throwable e) { e.printStackTrace(); }
  }
}

the output i get from this is

input stream position: 0
input stream position: 15
line: 0
line: 
line: 

and i see where i went wrong. each

br.readLine();

breaks exactly where it should. my confusion arose from the fact that

is.getChannel().position()

advanced to the end of the file rather than the end of the line. i had misunderstood that this value represents the last position read into the string - which is clearly incorrect. looks like this is the position read into the larger stream. thanks for helping to sort out my booboo.


Solution

  • InputStreamReader and BufferedReader both have their internal buffer they fill before doing anything else. So if you call BufferedReader#readLine a lot more data will be read in than just the characters until the first newline. Since both classes operate with buffers in the range of thousands of bytes (InputStreamReader) and chars (BufferedReader) it immediately reaches the end of your 15-byte long file the first time you call that method.

    At least that's what I read into it when you write "reads to the end of the file". If I guessed wrong, please ask a more precise question (ideally with some code that shows what you're doing leaving away and need of interpretation on our side)