@Test public void testFeedsCorrectData_whenFilePartiallyReadFromBeginning() throws Exception { byte[] fullFileContent = createFileContent(1024 * 1024 + 987654); RandomAccessFile raf = createRaf(fullFileContent); DataSource rafDataSource = new FileChannelDataSource(raf.getChannel()); ByteArrayDataSink dataSink = new ByteArrayDataSink(); int bytesToFeed = 1024 * 1024 + 12345; rafDataSource.feed(0, bytesToFeed, dataSink); byte[] expectedBytes = Arrays.copyOf(fullFileContent, bytesToFeed); byte[] resultBytes = getDataSinkBytes(dataSink); assertArrayEquals(expectedBytes, resultBytes); }
@Override public void feed(long offset, long size, DataSink sink) throws IOException { long sourceSize = size(); checkChunkValid(offset, size, sourceSize); if (size == 0) { return; } long chunkOffsetInFile = mOffset + offset; long remaining = size; ByteBuffer buf = ByteBuffer.allocateDirect((int) Math.min(remaining, MAX_READ_CHUNK_SIZE)); while (remaining > 0) { int chunkSize = (int) Math.min(remaining, buf.capacity()); int chunkRemaining = chunkSize; buf.limit(chunkSize); synchronized (mChannel) { mChannel.position(chunkOffsetInFile); while (chunkRemaining > 0) { int read = mChannel.read(buf); if (read < 0) { throw new IOException("Unexpected EOF encountered"); } chunkRemaining -= read; } } buf.flip(); sink.consume(buf); buf.clear(); chunkOffsetInFile += chunkSize; remaining -= chunkSize; } }
FileChannelDataSource implements DataSource { @Override public void feed(long offset, long size, DataSink sink) throws IOException { long sourceSize = size(); checkChunkValid(offset, size, sourceSize); if (size == 0) { return; } long chunkOffsetInFile = mOffset + offset; long remaining = size; ByteBuffer buf = ByteBuffer.allocateDirect((int) Math.min(remaining, MAX_READ_CHUNK_SIZE)); while (remaining > 0) { int chunkSize = (int) Math.min(remaining, buf.capacity()); int chunkRemaining = chunkSize; buf.limit(chunkSize); synchronized (mChannel) { mChannel.position(chunkOffsetInFile); while (chunkRemaining > 0) { int read = mChannel.read(buf); if (read < 0) { throw new IOException("Unexpected EOF encountered"); } chunkRemaining -= read; } } buf.flip(); sink.consume(buf); buf.clear(); chunkOffsetInFile += chunkSize; remaining -= chunkSize; } } }
FileChannelDataSource implements DataSource { @Override public void feed(long offset, long size, DataSink sink) throws IOException { long sourceSize = size(); checkChunkValid(offset, size, sourceSize); if (size == 0) { return; } long chunkOffsetInFile = mOffset + offset; long remaining = size; ByteBuffer buf = ByteBuffer.allocateDirect((int) Math.min(remaining, MAX_READ_CHUNK_SIZE)); while (remaining > 0) { int chunkSize = (int) Math.min(remaining, buf.capacity()); int chunkRemaining = chunkSize; buf.limit(chunkSize); synchronized (mChannel) { mChannel.position(chunkOffsetInFile); while (chunkRemaining > 0) { int read = mChannel.read(buf); if (read < 0) { throw new IOException("Unexpected EOF encountered"); } chunkRemaining -= read; } } buf.flip(); sink.consume(buf); buf.clear(); chunkOffsetInFile += chunkSize; remaining -= chunkSize; } } FileChannelDataSource(FileChannel channel);  FileChannelDataSource(FileChannel channel, long offset, long size); }
FileChannelDataSource implements DataSource { @Override public void feed(long offset, long size, DataSink sink) throws IOException { long sourceSize = size(); checkChunkValid(offset, size, sourceSize); if (size == 0) { return; } long chunkOffsetInFile = mOffset + offset; long remaining = size; ByteBuffer buf = ByteBuffer.allocateDirect((int) Math.min(remaining, MAX_READ_CHUNK_SIZE)); while (remaining > 0) { int chunkSize = (int) Math.min(remaining, buf.capacity()); int chunkRemaining = chunkSize; buf.limit(chunkSize); synchronized (mChannel) { mChannel.position(chunkOffsetInFile); while (chunkRemaining > 0) { int read = mChannel.read(buf); if (read < 0) { throw new IOException("Unexpected EOF encountered"); } chunkRemaining -= read; } } buf.flip(); sink.consume(buf); buf.clear(); chunkOffsetInFile += chunkSize; remaining -= chunkSize; } } FileChannelDataSource(FileChannel channel);  FileChannelDataSource(FileChannel channel, long offset, long size); @Override long size(); @Override FileChannelDataSource slice(long offset, long size); @Override void feed(long offset, long size, DataSink sink); @Override void copyTo(long offset, int size, ByteBuffer dest); @Override ByteBuffer getByteBuffer(long offset, int size); }
FileChannelDataSource implements DataSource { @Override public void feed(long offset, long size, DataSink sink) throws IOException { long sourceSize = size(); checkChunkValid(offset, size, sourceSize); if (size == 0) { return; } long chunkOffsetInFile = mOffset + offset; long remaining = size; ByteBuffer buf = ByteBuffer.allocateDirect((int) Math.min(remaining, MAX_READ_CHUNK_SIZE)); while (remaining > 0) { int chunkSize = (int) Math.min(remaining, buf.capacity()); int chunkRemaining = chunkSize; buf.limit(chunkSize); synchronized (mChannel) { mChannel.position(chunkOffsetInFile); while (chunkRemaining > 0) { int read = mChannel.read(buf); if (read < 0) { throw new IOException("Unexpected EOF encountered"); } chunkRemaining -= read; } } buf.flip(); sink.consume(buf); buf.clear(); chunkOffsetInFile += chunkSize; remaining -= chunkSize; } } FileChannelDataSource(FileChannel channel);  FileChannelDataSource(FileChannel channel, long offset, long size); @Override long size(); @Override FileChannelDataSource slice(long offset, long size); @Override void feed(long offset, long size, DataSink sink); @Override void copyTo(long offset, int size, ByteBuffer dest); @Override ByteBuffer getByteBuffer(long offset, int size);  }