Too late for the original poster, but anyway.
I tried to reproduce your problem (but with a slightly different sample, I duplicated a large file using channels):
public static void main(String[] args) throws IOException, InterruptedException, ExecutionException { final InputStream inputStream = new FileInputStream("/home/me/Store/largefile"); final ReadableByteChannel inputChannel = Channels.newChannel(inputStream); final AsynchronousFileChannel outputChannel = AsynchronousFileChannel.open( FileSystems.getDefault().getPath( "/home/me/Store/output"), StandardOpenOption.CREATE, StandardOpenOption.WRITE); outputChannel.lock(); final ByteBuffer buffer = ByteBuffer.allocate(4096); int position = 0; int recievedBytes = 0; Future<Integer> lastWrite = null; while ((recievedBytes = inputChannel.read(buffer)) >= 0 || buffer.position() != 0) { System.out.println("Recieved bytes: " + recievedBytes); System.out.println("Buffer position: " + buffer.position()); buffer.flip(); lastWrite = outputChannel.write(buffer, position);
In each iteration of the loop, we read a piece of data from the input stream, then we โpushโ this fragment into the output stream. The current thread does not wait for the completion of writing, it continues, so we can perform additional work. But before the new iteration, we must wait until the writing is complete. Try to comment
if (lastWrite != null) lastWrite.get();
and you will get
java.nio.BufferOverflowException .
Your code gave me a hint for using Future to handle the last write operation. But you missed the wait for the last operation.
In addition, I skipped the additional setting, which is in your fragment (just for simplicity, no additional setting is required when working with files).
source share