buff.limit(readSize); ch.read(buff, position, null, new java.nio.channels.CompletionHandler<Integer, Object>() {
/** {@inheritDoc} */ @Override public int read(byte[] buf, int off, int length) throws IOException { ChannelOpFuture fut = holder.get(); fut.reset(); ch.read(ByteBuffer.wrap(buf, off, length), position, this, fut); try { return fut.getUninterruptibly(); } catch (IgniteCheckedException e) { throw new IOException(e); } }
/** {@inheritDoc} */ @Override public int read(ByteBuffer destBuf) throws IOException { ChannelOpFuture fut = holder.get(); fut.reset(); ch.read(destBuf, position, this, fut); try { return fut.getUninterruptibly(); } catch (IgniteCheckedException e) { throw new IOException(e); } }
/** {@inheritDoc} */ @Override public int read(ByteBuffer destBuf, long position) throws IOException { ChannelOpFuture fut = holder.get(); fut.reset(); ch.read(destBuf, position, null, fut); try { return fut.getUninterruptibly(); } catch (IgniteCheckedException e) { throw new IOException(e); } finally { asyncFuts.remove(fut); } }
@Override public void completed(Integer read, DataBuffer dataBuffer) { if (read != -1) { long pos = this.position.addAndGet(read); dataBuffer.writePosition(read); this.sink.next(dataBuffer); if (!this.disposed.get()) { DataBuffer newDataBuffer = this.dataBufferFactory.allocateBuffer(this.bufferSize); ByteBuffer newByteBuffer = newDataBuffer.asByteBuffer(0, this.bufferSize); this.channel.read(newByteBuffer, pos, newDataBuffer, this); } } else { release(dataBuffer); this.sink.complete(); } }
/** * Obtain a {@code AsynchronousFileChannel} from the given supplier, and read it into a * {@code Flux} of {@code DataBuffer}s, starting at the given position. Closes the * channel when the flux is terminated. * @param channelSupplier the supplier for the channel to read from * @param position the position to start reading from * @param dataBufferFactory the factory to create data buffers with * @param bufferSize the maximum size of the data buffers * @return a flux of data buffers read from the given channel */ public static Flux<DataBuffer> readAsynchronousFileChannel(Callable<AsynchronousFileChannel> channelSupplier, long position, DataBufferFactory dataBufferFactory, int bufferSize) { Assert.notNull(channelSupplier, "'channelSupplier' must not be null"); Assert.notNull(dataBufferFactory, "'dataBufferFactory' must not be null"); Assert.isTrue(position >= 0, "'position' must be >= 0"); Assert.isTrue(bufferSize > 0, "'bufferSize' must be > 0"); DataBuffer dataBuffer = dataBufferFactory.allocateBuffer(bufferSize); ByteBuffer byteBuffer = dataBuffer.asByteBuffer(0, bufferSize); Flux<DataBuffer> result = Flux.using(channelSupplier, channel -> Flux.create(sink -> { AsynchronousFileChannelReadCompletionHandler completionHandler = new AsynchronousFileChannelReadCompletionHandler(channel, sink, position, dataBufferFactory, bufferSize); channel.read(byteBuffer, position, dataBuffer, completionHandler); sink.onDispose(completionHandler::dispose); }), DataBufferUtils::closeChannel); return result.doOnDiscard(PooledDataBuffer.class, DataBufferUtils::release); }
@Override public void completed(Integer read, DataBuffer dataBuffer) { if (read != -1) { long pos = this.position.addAndGet(read); dataBuffer.writePosition(read); this.sink.next(dataBuffer); if (!this.disposed.get()) { DataBuffer newDataBuffer = this.dataBufferFactory.allocateBuffer(this.bufferSize); ByteBuffer newByteBuffer = newDataBuffer.asByteBuffer(0, this.bufferSize); this.channel.read(newByteBuffer, pos, newDataBuffer, this); } } else { release(dataBuffer); this.sink.complete(); } }
/** * Obtain a {@code AsynchronousFileChannel} from the given supplier, and read it into a * {@code Flux} of {@code DataBuffer}s, starting at the given position. Closes the * channel when the flux is terminated. * @param channelSupplier the supplier for the channel to read from * @param position the position to start reading from * @param dataBufferFactory the factory to create data buffers with * @param bufferSize the maximum size of the data buffers * @return a flux of data buffers read from the given channel */ public static Flux<DataBuffer> readAsynchronousFileChannel(Callable<AsynchronousFileChannel> channelSupplier, long position, DataBufferFactory dataBufferFactory, int bufferSize) { Assert.notNull(channelSupplier, "'channelSupplier' must not be null"); Assert.notNull(dataBufferFactory, "'dataBufferFactory' must not be null"); Assert.isTrue(position >= 0, "'position' must be >= 0"); Assert.isTrue(bufferSize > 0, "'bufferSize' must be > 0"); DataBuffer dataBuffer = dataBufferFactory.allocateBuffer(bufferSize); ByteBuffer byteBuffer = dataBuffer.asByteBuffer(0, bufferSize); Flux<DataBuffer> result = Flux.using(channelSupplier, channel -> Flux.create(sink -> { AsynchronousFileChannelReadCompletionHandler completionHandler = new AsynchronousFileChannelReadCompletionHandler(channel, sink, position, dataBufferFactory, bufferSize); channel.read(byteBuffer, position, dataBuffer, completionHandler); sink.onDispose(completionHandler::dispose); }), DataBufferUtils::closeChannel); return result.doOnDiscard(PooledDataBuffer.class, DataBufferUtils::release); }
@Test public void readAsynchronousFileChannelError() throws Exception { AsynchronousFileChannel channel = mock(AsynchronousFileChannel.class); doAnswer(invocation -> { ByteBuffer byteBuffer = invocation.getArgument(0); byteBuffer.put("foo".getBytes(StandardCharsets.UTF_8)); byteBuffer.flip(); long pos = invocation.getArgument(1); assertEquals(0, pos); DataBuffer dataBuffer = invocation.getArgument(2); CompletionHandler<Integer, DataBuffer> completionHandler = invocation.getArgument(3); completionHandler.completed(3, dataBuffer); return null; }).doAnswer(invocation -> { DataBuffer dataBuffer = invocation.getArgument(2); CompletionHandler<Integer, DataBuffer> completionHandler = invocation.getArgument(3); completionHandler.failed(new IOException(), dataBuffer); return null; }) .when(channel).read(any(), anyLong(), any(), any()); Flux<DataBuffer> result = DataBufferUtils.readAsynchronousFileChannel(() -> channel, this.bufferFactory, 3); StepVerifier.create(result) .consumeNextWith(stringConsumer("foo")) .expectError(IOException.class) .verify(Duration.ofSeconds(3)); }
private void doRead(Buffer writeBuff, int offset, ByteBuffer buff, long position, Handler<AsyncResult<Buffer>> handler) { ch.read(buff, position, null, new java.nio.channels.CompletionHandler<Integer, Object>() { long pos = position; private void done() { context.runOnContext((v) -> { buff.flip(); writeBuff.setBytes(offset, buff); buff.compact(); handler.handle(Future.succeededFuture(writeBuff)); }); } public void completed(Integer bytesRead, Object attachment) { if (bytesRead == -1) { //End of file done(); } else if (buff.hasRemaining()) { // partial read pos += bytesRead; // resubmit doRead(writeBuff, offset, buff, pos, handler); } else { // It's been fully written done(); } } public void failed(Throwable t, Object attachment) { context.runOnContext((v) -> handler.handle(Future.failedFuture(t))); } }); }
/** * @param off Offset. * @param buf Byte buffer. * @return Future. */ public Future<Integer> read(long off, ByteBuffer buf) { return readCh.read(buf, off); }
@Override protected void requestAsync(Fiber current, CompletionHandler<Integer, Fiber> completionHandler) { ac.read(dst, position, current, completionHandler); } }.run();
@Override public <A> void read(final ByteBuffer dst, final long position, final A attachment, final CompletionHandler<Integer, ? super A> handler) { chan.read(dst, position, attachment, handler); }
@Override public Future<Integer> read(final ByteBuffer dst, final long position) { return chan.read(dst, position); }
private void doRead() { // use local variable to limit volatile reads long pos = position; ByteBuffer innerBuf = ByteBuffer.allocate(Math.min(chunkSize, maxRequired(pos))); fileChannel.read(innerBuf, pos, innerBuf, this); }
@Override protected void requestAsync() { ac.read(dst, position, null, makeCallback()); } }.runSneaky();
AsynchronousFileChannel ch = AsynchronousFileChannel.open(path); final ByteBuffer buf = ByteBuffer.allocate(1024); ch.read(buf, 0, 0, new CompletionHandler() { public void completed(Integer result, Integer length){ .. } public void failed(Throwable exc, Integer length) { .. } } );
/** {@inheritDoc} */ @Override public int read(byte[] buf, int off, int length) throws IOException { ChannelOpFuture fut = holder.get(); fut.reset(); ch.read(ByteBuffer.wrap(buf, off, length), position, this, fut); try { return fut.getUninterruptibly(); } catch (IgniteCheckedException e) { throw new IOException(e); } }
/** {@inheritDoc} */ @Override public int read(ByteBuffer destBuf) throws IOException { ChannelOpFuture fut = holder.get(); fut.reset(); ch.read(destBuf, position, this, fut); try { return fut.getUninterruptibly(); } catch (IgniteCheckedException e) { throw new IOException(e); } }
@Test(dataProvider = "Write-Read-Data-Provider") public void hasMoreToRead(int read, long wantedPosition, long wantedSize) { Integer bytesRead = Integer.valueOf(read); when(attachment.getPosition()).thenReturn(wantedPosition); when(attachment.getSize()).thenReturn(wantedSize); when(writeReadRunnable.isFinished()).thenReturn(false); readingCompletionHandler.completed(bytesRead, attachment); verify(attachment).setPosition(wantedPosition + read); verify(attachment).setSize(wantedSize - read); verify(channel, times(1)).read(byteBuffer, wantedPosition + read, attachment, readingCompletionHandler); verifyZeroInteractions(writeReadRunnableFuture, byteBuffer); }