package lsm.base; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import com.google.common.base.Preconditions; import io.netty.buffer.ByteBuf; import io.netty.buffer.PooledByteBufAllocator; import io.netty.buffer.Unpooled; /** * ByteBuf 工具类 * @author bird * */ public class ByteBufUtils { /** * 将buffer中的数据写入文件 * @param channel * @param buffer * @throws IOException */ public static void write(FileChannel channel, ByteBuf buffer) throws IOException { // 建立bytebuffer以便写入文件 ByteBuffer tmpBuffer = ByteBuffer.allocate(buffer.readableBytes()); // 将bytebuf中的数据导入bytebuffer中 buffer.slice().readBytes(tmpBuffer); // bytebuffer数据写入fileChannel tmpBuffer.flip(); channel.write(tmpBuffer); } /** * 读取文件数据到ByteBuf中 * @param channel * @param buffer * @throws IOException */ public static void read(FileChannel channel, ByteBuf buffer) throws IOException { // 建立bytebuffer以便写入文件 ByteBuffer tmpBuffer = ByteBuffer.allocate(buffer.capacity()); // 文件数据写入buffer channel.read(tmpBuffer); tmpBuffer.flip(); // bytebuffer写入byteBuf buffer.writeBytes(tmpBuffer); } public static void putVarByte(ByteBuf dst, byte data) { Preconditions.checkArgument(dst.writableBytes() >= Byte.BYTES); dst.writeByte(data); } public static void putVarInt(ByteBuf dst, int data) { Preconditions.checkArgument(dst.writableBytes() >= Integer.BYTES); dst.writeInt(data); } public static void putVarLong(ByteBuf dst, long data) { Preconditions.checkArgument(dst.writableBytes() >= Long.BYTES); dst.writeLong(data); } public static void putVarWithLenPrefix(ByteBuf dst, ByteBuf data) { Preconditions.checkArgument(dst.writableBytes() >= (data.readableBytes() + Integer.BYTES)); dst.writeInt(data.readableBytes()); dst.writeBytes(data.slice()); } public static void putVarWithLenPrefix(ByteBuf dst, byte[] data) { Preconditions.checkArgument(dst.writableBytes() >= (data.length + Integer.BYTES)); dst.writeInt(data.length); dst.writeBytes(data); } public static ByteBuf getVarWithLenPrefix(ByteBuf src) { Preconditions.checkArgument(src.isReadable()); int len = src.readInt(); ByteBuf ret = src.readSlice(len); return ret; } /** * 批量记录索引位置 * @param buffers */ public static void markIndex(ByteBuf... buffers) { for(ByteBuf buffer : buffers) { // 记录bytebuf信息 buffer.markReaderIndex(); buffer.markWriterIndex(); } } /** * 批量恢复索引位置 * @param buffers */ public static void resetIndex(ByteBuf... buffers) { for(ByteBuf buffer : buffers) { // 恢复bytebuf信息 buffer.resetReaderIndex(); buffer.resetWriterIndex(); } } /** * ByteBuf内容生成字符串 * @param buf * @return */ public static String buf2Str(ByteBuf buf) { String str; // 处理堆缓冲区 if(buf.hasArray()) { str = new String(buf.array(), buf.arrayOffset() + buf.readerIndex(), buf.readableBytes()); } else { // 处理直接缓冲区以及复合缓冲区 byte[] bytes = new byte[buf.readableBytes()]; buf.getBytes(buf.readerIndex(), bytes); str = new String(bytes, 0, buf.readableBytes()); } return str; } /**字符串转byteBuf * @param str * @return */ public static ByteBuf str2Buf(String str) { return Unpooled.wrappedBuffer(str.getBytes()); } /** * 将buf转换为byte[] * @param buf * @return */ public static byte[] buf2Bytes(ByteBuf buf) { Preconditions.checkNotNull(buf); byte[] bytes = new byte[buf.readableBytes()]; buf.slice().readBytes(bytes); return bytes; } }