31

How to get a byte array from ByteBuf efficiently in the code below? I need to get the array and then serialize it.

package testingNetty;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

public class ServerHandler extends  ChannelInboundHandlerAdapter {
     @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) {
         System.out.println("Message receive");
         ByteBuf buff = (ByteBuf) msg;
             // There is I need get bytes from buff and make serialization
         byte[] bytes = BuffConvertor.GetBytes(buff);
        }

        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { 
            // Close the connection when an exception is raised.
            cause.printStackTrace();
            ctx.close();
        }

}
4
  • Can you please post the complete code. Also mention the which version of netty you are using? Commented Oct 10, 2013 at 13:12
  • I use 4.0.9 version of Netty Commented Oct 10, 2013 at 13:16
  • So what's problem is? What do you mean by bytes massive in the above context? Commented Oct 10, 2013 at 13:35
  • Bytes massive means a byte[] wich contains seriziable object Commented Oct 10, 2013 at 14:12

2 Answers 2

91
ByteBuf buf = ...
byte[] bytes = new byte[buf.readableBytes()];
buf.readBytes(bytes);

If you don't want the readerIndex to change:

ByteBuf buf = ...
byte[] bytes = new byte[buf.readableBytes()];
int readerIndex = buf.readerIndex();
buf.getBytes(readerIndex, bytes);

If you want to minimize the memory copy, you can use the backing array of the ByteBuf, if it's available:

ByteBuf buf = ...
byte[] bytes;
int offset;
int length = buf.readableBytes();

if (buf.hasArray()) {
    bytes = buf.array();
    offset = buf.arrayOffset();
} else {
    bytes = new byte[length];
    buf.getBytes(buf.readerIndex(), bytes);
    offset = 0;
}

Please note that you can't simply use buf.array(), because:

  • Not all ByteBufs have backing array. Some are off-heap buffers (i.e. direct memory)
  • Even if a ByteBuf has a backing array (i.e. buf.hasArray() returns true), the following isn't necessarily true because the buffer might be a slice of other buffer or a pooled buffer:
    • buf.array()[0] == buf.getByte(0)
    • buf.array().length == buf.capacity()
Sign up to request clarification or add additional context in comments.

8 Comments

@user2132106 would like to know if he can do byte[] ar= buf.array() (if I understand the post correctly).
Updated the answer for him.
@trustin what's the purpose of the offset here?
I tested with real data: the second way (minimize the memory copy) is wrong. Java platform: Oracle 1.8; netty version: 4.1.58.Final.
@Fireburn offset tells at which position in the array the first byte starts.
|
6

Another option is ByteBufUtil.getBytes(ByteBuf buf, int start, int length, boolean copy)

See ByteBufUtil

2 Comments

There is indeed an option to share the array instead of copying it (if possible)
Thanks @TuomasKiviaho . I updated my answer per your comment.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.