1

I try to use AsynchronousFileChannel to implement copying file. The AsynchronousFileChannel objects for read and write are declare as

AsynchronousFileChannel asyncRead = AsynchronousFileChannel.open(sourcePath);
AsynchronousFileChannel asyncWrite = AsynchronousFileChannel.open(targetPath, StandardOpenOption.WRITE, StandardOpenOption.CREATE);

The CompletionHandler for read looks like

CompletionHandler<Integer, ByteBuffer> handlerRead = new CompletionHandler<Integer, ByteBuffer>() {

        @Override
        public void completed(Integer arg0, ByteBuffer arg1) {
            System.out.println("finished read ...");

            // question line
            asyncWrite.write(ByteBuffer.wrap(arg1.array()), 0, null, handlerWrite);
        }

        @Override
        public void failed(Throwable arg0, ByteBuffer arg1) {
            System.out.println("failed to read ...");
        }
    };

Then I start file read by

asyncRead.read(buffer, 0, buffer, handlerRead);

The question is, after the read is complete, If I write file (please see the the comment "question line" to see where it is called)

// no output
asyncWrite.write(arg1, 0, null, handlerWrite);

there will be no content written out. I have to wrap the buffer again

// works fine
asyncWrite.write(ByteBuffer.wrap(arg1.array()), 0, null, handlerWrite);

in order to see the content written out

My question is, what is the reason I have to use the ByteBuffer to wrap the content of another ByteBuffer?

1 Answer 1

3

what is the reason I have to use the ByteBuffer to wrap the content of another ByteBuffer?

You don't. You should have flipped the original ByteBuffer instead. You got a similar effect by calling wrap(), which sets the position of the newly wrapped ByteBuffer to zero.

Sign up to request clarification or add additional context in comments.

4 Comments

I tried asyncWrite.write((ByteBuffer)arg1.flip(), 0, null, handlerWrite);, it also works. Thank you for the hint, although I still don't know what's happened under the hood yet.
So have a look the Javadoc for flip(). Its purpose is to put a Buffer into a writable state. Normally they are in a readable state. You should compact() or clear() afterwards if you're going to read into it again.
Yep, I read the doc already, but don't digest it yet. From what you said, it sounds like an iterator that I have to do something to move the pointer to the head if I want to iterate the list for the 2nd time. Is my understanding correct?
No, it's not an iterator. NIO Buffers exist in two states: ready for read and ready for write. Unfortunately. You have to flip() to get from read-ready to write-ready, and you have to compact() or clear() to get back again. Poor design IMHO, especially the misnamed flip() operation, which isn't reversible despite its name.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.