title: Netty using ByteBuffer from pooled direct ByteBuf
body: <p>I try to understand few things about netty's ByteBuf and its relation to nio.ByteBuffer.</p>
  <p>the problem I try to solve is that my server has to return random portion of a file located on the server - this was implemented using nio.FileChannel and FChannel is depending on nio.ByteBuffer.</p>
  <p>As I understand allocating direct ByteBuffer should be pooled - but there is no native pool implementation in nio - and my application should add such layer so I dont pay penalty of creating direct buffer for each request.</p>
  <p>My application uses netty as server so I thought that I can use netty's pooled direct ByteBuff and access ByteBuffer it wraps using</p>
  <pre><code>var byteBuf = ctx.alloc().directBuffer(1024); // (1)
  var chunkHolder = byteBuf.nioBuffer(0, byteBuf.capacity()); // (2)
  </code></pre>
  <p>so everything works as expected but <code>.nioBuffer</code> or <code>.nioBuffers</code> create a copy of the buffer - not just a view on ByteBuff so after writing to <code>chunkHolder</code> positions/limits/etc of <code>byteBuf</code> remains unchanged!</p>
  <p>I have to use</p>
  <pre><code>var flip = chunkHolder.flip(); // (2)
  var content = Unpooled.wrappedBuffer(flip);
  ctx.writeAndFlush(content)
     .addListener(f -&gt; byteBuf.release()); (1)
  </code></pre>
  <p>so object are created again, the only good thing is that that <em>memory is not copied</em> - <em>if I am not mistaken</em>.</p>
  <p>the question: can I do something smarter so there is no data copying between tcp transport and file read with minimal garbage? is nio somehow helps in maintaining direct ByteBuffers?</p>
  <p>The best idea that is coming to my mind is to wrap BytBuf with ByteBuffer-like implementation and proxy all write operation back to underlying byteBuf.</p>
  <p>PS:
  I ve looked also at <code>io/netty/channel/DefaultFileRegion.java</code> as it works with nio.FileChannel but behind the scene netty uses nio directly</p>
  <pre><code>raf = new RandomAccessFile(filePath, &quot;r&quot;);
  ctx.write(new DefaultFileRegion(raf.getChannel(), 0, length));
  </code></pre>