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


Reply via email to