code: static void readBytes(ByteBufAllocator allocator, ByteBuffer buffer, int position, int length, OutputStream out)
              throws IOException {
          if (buffer.hasArray()) {
              out.write(buffer.array(), position + buffer.arrayOffset(), length);
          } else {
              int chunkLen = Math.min(length, WRITE_CHUNK_SIZE);
              buffer.clear().position(position);
  
              if (length <= MAX_TL_ARRAY_LEN || !allocator.isDirectBufferPooled()) {
                  getBytes(buffer, threadLocalTempArray(chunkLen), 0, chunkLen, out, length);
              } else {
                  // if direct buffers are pooled chances are good that heap buffers are pooled as well.
                  ByteBuf tmpBuf = allocator.heapBuffer(chunkLen);
                  try {
                      byte[] tmp = tmpBuf.array();
                      int offset = tmpBuf.arrayOffset();
                      getBytes(buffer, tmp, offset, chunkLen, out, length);
                  } finally {
                      tmpBuf.release();
                  }
              }
          }
      }
docs: Read bytes from the given {@link ByteBuffer} into the given {@link OutputStream} using the {@code position} and
  {@code length}. The position and limit of the given {@link ByteBuffer} may be adjusted.