Search code examples
javabytebufferfilechannel

FIleChannel, ByteBuffer why is postion 0 after read?


public class CodingDecoding
{
    public static void main(String[] args)
    {

        try (
                FileChannel out = FileChannel.open(Paths.get("out.txt"),
                        StandardOpenOption.READ,
                        StandardOpenOption.WRITE,
                        StandardOpenOption.CREATE);
                FileChannel in = FileChannel.open(Paths.get("in.txt"),
                        StandardOpenOption.READ,
                        StandardOpenOption.WRITE,
                        StandardOpenOption.CREATE);

        )
        {

            // write "Hello" to buffer and flip to make buffer ready for writing
            ByteBuffer buffer = ByteBuffer.allocate(1000);
            buffer.put("Hello".getBytes());
            System.out.println(buffer); // [pos=5 lim=1000 cap=1000]
            buffer.flip();
            System.out.println(buffer); // [pos=0 lim=5 cap=1000]

            // write
            in.write(buffer);
            System.out.println(buffer); //[pos=5 lim=5 cap=1000]

            // flip for reading
            buffer.flip();
            System.out.println(buffer); //[pos=0 lim=5 cap=1000]


            // read
            in.read(buffer);  
            System.out.println(buffer);// [pos=0 lim=5 cap=1000] why pos=0 not pos=5? I didn't read anything?

            // flip for writing
            buffer.flip();
            System.out.println(buffer); //[pos=0 lim=0 cap=1000] so I write nothing to out

            out.write(buffer);
        }
        catch (IOException ioException)
        {
            ioException.printStackTrace();
        }


    }
}

Can you explain me why pos after read is 0 not 5? I want write "Hello" to in, then read from in and write "Hello" to out. But I dont understand why pos is 0 after read.It's like I haven't read anything.

I tried to write "Hello" to in then read from in, and finally write to out. But I don't understand why is position of buffer = 0 after read.As if I didn't read anything?


Solution

  • Your FileChannel object (in) is a channel and, itself, has a position. The idea is that after calling in.write(buffer), you can.. call in.write(buffer) some more. Your question implies that you think every method call on a FileChannel stands alone and goes through the whole process of actually asking the OS to open the file, then do the thing the method call implies (read, or write), and then close it - each method call stands on its own and is independent of all others.

    Not how it works.

    The act of creating the FileChannel opens an OS level resource, and all method calls affect each other. When you call write, the FileChannel is now at position 5 in the new file you have. When you then call read, obviously, you get nothing: That FileChannel is at the end of the file so there are no bytes to be read.

    How to fix it

    either close the channel and open a new one, or, use position to hop around: Add a call to in.position(0L) after calling in.write and before calling in.read.