ByteBuffer常用方法

分配空间

    public static void main(String[] args) {
        System.out.println(ByteBuffer.allocate(10).getClass());
        System.out.println(ByteBuffer.allocateDirect(10).getClass());
    }

WX20220423-201021@2x

  • HeapByteBuffer java堆内存,读写效率低,受GC影响
  • DirectByteBuffer 直接内存,读写效率高(少一次拷贝),但是分配效率低,可能造成内存泄漏,不受GC影响,netty在此基础上封装了一层

向buffer写

  • 调用channel的read方法
int readBytes = channel.read(buf)
  • 调用buffer自己的put方法
buf.put((byte)127)

从buffer读

  • 调用channel的write方法
int writeBytes = channel.write(buf)
  • 调用buffer自己的get方法
byte b = buffer.get()

get方法会让position读指针向后走,如果想重复读取数据:

  1. 可以调用rewind方法将posiiton重置为0
  2. 或者用get(int i)方法获取索引i的内容,它不会移动读指针
  3. mark & reset方法
       // mark做一个标记,记录position位置,reset是将position重置到mark的位置
       buffer.get();
       buffer.mark(); // 加标记,索引为1的位置
       buffer.get();
       buffer.reset(); // 将索引重置到1

字符串转为ByteBuffer

        // 1.字符串转为ByteBuffer
        ByteBuffer buffer1 = ByteBuffer.allocate(16);
        buffer1.put("hello".getBytes());

        // 2. Charset
        ByteBuffer buffer2 = StandardCharsets.UTF_8.encode("hello");

        // 3. wrap
        ByteBuffer buffer3 = ByteBuffer.wrap("hello".getBytes());

        // 4. 转为字符串
        // 记得要切换读模式
        buffer1.flip();
        String str1 = StandardCharsets.UTF_8.decode(buffer1).toString();
        System.out.println(str1);

        // 5. 这种不需要切换模式
        String str2 = StandardCharsets.UTF_8.decode(buffer2).toString();
        System.out.println(str2);

ByteBuffer分散读集中写

channel.read(new ByteBuffer[]{a,b,c})
channel.write(new ByteBuffer[]{b1,b2,b3})

分散读和集中写可以减少拷贝次数,提高性能