This discussion is archived
7 Replies Latest reply: Apr 11, 2013 8:50 AM by 963772 RSS

Java NIO - Invoking compact() method on buffer object

963772 Newbie
Currently Being Moderated
Hello,

I have a question about invoking the compact() method on a buffer object. For instance consider the following piece of code:


import java.io.*;
import java.nio.*;
import java.nio.channels.*;

     public class FileCopy3 {
public static void main(String[] args) throws IOException {
ReadableByteChannel in = new FileInputStream(args[0]).getChannel();
WritableByteChannel out;
if (args.length > 1) out = new FileOutputStream(args[1]).getChannel();
else out = Channels.newChannel(System.out);

copy(in, out);

}

public static void copy(ReadableByteChannel in, WritableByteChannel out)
throws IOException
     {

ByteBuffer buffer = ByteBuffer.allocateDirect(32 * 1024);
     while(in.read(buffer) != -1 || buffer.position() > 0) {
buffer.flip();
out.write(buffer);
buffer.compact();
}
}
}

why should we concerning about compacting the buffer after writing it's contents thoroughly ?! Is it not true that the write() method above, should drain the whole buffer contents and write its contents to the output channel? Then why should we concern about the remaining data ? Is it not fully drained ? Where does this remaining data came from ?


Thanks,

Edited by: 960769 on Apr 10, 2013 2:32 AM
  • 1. Re: Java NIO - Invoking compact() method on buffer object
    EJP Guru
    Currently Being Moderated
    why should we concerning about compacting the buffer after writing its contents thoroughly?
    (1) That code isn't guaranteed to 'write the contents thoroughly'.
    (2) To remove what has been written from the buffer so it won't be written again.
    (3) To reconfigure the buffer so it is ready for another read, i.e. undo the effects of flip().
    Is it not true that the write() method above, should drain the whole buffer contents
    No.
    and write its contents to the output channel?
    As much as it can, yes.
    Then why should we concern about the remaining data?
    Because it hasn't been written yet.
    Is it not fully drained?
    Not necessarily. That's why write() returns a count.
    Where does this remaining data came from?
    From the read().
  • 2. Re: Java NIO - Invoking compact() method on buffer object
    963772 Newbie
    Currently Being Moderated
    Thank you for your reply,

    I'm a bit confused ... If the buffer demarcate the available data by means of position and limit markers ( as it's done by calling flip ) and the write method returns the number of number of bytes which are read, then why it is not guaranteed that the write() method drains the buffer contents thoroughly ?

    Sam,
  • 3. Re: Java NIO - Invoking compact() method on buffer object
    EJP Guru
    Currently Being Moderated
    The question is fallacious. The 'why' part doesn't follow logically from the 'if' part.

    There is no wording in the specification of the write() method that suggests it is required to transfer everything, and, again, that's why it returns a count. Compare OutputStream.write(), which is required to transfer everything, and doesn't return a count.
  • 4. Re: Java NIO - Invoking compact() method on buffer object
    963772 Newbie
    Currently Being Moderated
    Then i must ask why the write method is not guaranteed to drain the whole buffer ?! Technical articles often address this situation as the effect of partial read or write. When does this partial read/write happen? Why sometimes some bytes remain in the buffer after the read and write operations ?

    Edited by: 960769 on Apr 11, 2013 4:28 PM

    Edited by: 960769 on Apr 11, 2013 4:33 PM
  • 5. Re: Java NIO - Invoking compact() method on buffer object
    EJP Guru
    Currently Being Moderated
    Because the medium being written to may not permit it. For example, a socket in non-blocking mode. If all the data won't fit into the socket send buffer in the kernel, the write() method has no other sensible option but to transfer what does fit and return that count, and rely in the application retrying later with the remaining data.
  • 6. Re: Java NIO - Invoking compact() method on buffer object
    gimbal2 Guru
    Currently Being Moderated
    Point being: you can't ask for implementation details when you're talking about an API. There are no implementation details, it might be anything. You'd first have to define a specific context (local filesystem, over a network, beaming through space from satelite to satelite, etc.) and perhaps then you could go into specifics but even then - you shouldn't really care about the WHY of a specific case, you can't make any assumptions about it being the way it is or STAYING the way it is so you just need deal with the solution that is always safe regardless of context, environment and implementation. Which is usually the most work, but that's life.
  • 7. Re: Java NIO - Invoking compact() method on buffer object
    963772 Newbie
    Currently Being Moderated
    Thank you EJP, this is very helpful.

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points