matthijsln edited a comment on pull request #214: URL: https://github.com/apache/commons-compress/pull/214#issuecomment-892504852
This would work without a copy buffer: ``` public static byte[] readRange(final ReadableByteChannel input, final int len) throws IOException { final ByteBuffer b = ByteBuffer.allocate(len); while (b.hasRemaining()) { if (input.read(b) <= 0) { break; } } return Arrays.copyOf(b.array(), b.position()); } ``` With a copy buffer: ``` public static byte[] readRange(final ReadableByteChannel input, final int len) throws IOException { final ByteArrayOutputStream output = new ByteArrayOutputStream(); final ByteBuffer b = ByteBuffer.allocate(Math.min(len, COPY_BUF_SIZE)); int read = 0; while (read < len) { // Make sure we never read more than len bytes b.limit(Math.min(len - read, b.capacity())); final int readNow = input.read(b); if (readNow <= 0) { break; } output.write(b.array(), 0, readNow); b.rewind(); read += readNow; } return output.toByteArray(); } ``` Additional test case for reading more than the copy buffer length (of course COPY_BUF_SIZE can be made more accessible instead of using reflection): ``` @Test public void readRangeMoreThanCopyBufferSize() throws Exception { final Field COPY_BUF_SIZE = IOUtils.class.getDeclaredField("COPY_BUF_SIZE"); COPY_BUF_SIZE.setAccessible(true); final int copyBufSize = (int)COPY_BUF_SIZE.get(null); // Make an input that requires two read loops byte[] input = new byte[copyBufSize + 10]; try (SeekableByteChannel in = new SeekableInMemoryByteChannel(input)) { // Ask for less than the input length, but more than the buffer size int toRead = copyBufSize + 1; byte[] read = IOUtils.readRange(in, toRead); assertEquals(toRead, read.length); assertEquals(toRead, in.position()); } } ``` Hope this is correct :) What version is preferable? I don't think a copy buffer in itself is needed, although the maximum memory requirement is `len * 2` instead of `len + COPY_BUF_SIZE`. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: issues-unsubscr...@commons.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org