NIO 缓冲区 ByteBuffer 基本认识

一、差别

java.nio.HeapByteBuffer

  0. 获取方式:ByteBuffer.allocate(int value);

  1. java堆内存,读写效率较低,但分配内存较块。

  2. 受到 GC 影响。
java.nio.DirectByteBuffer

  1. 直接内存(系统内存),读写效率较高(少一次copy),分配内存较慢。

  2. 不受 GC 影响。

  3. 使用不当,则容易造成内存泄漏。

 

二、常用方法

// 获取FileChannel 1.输入输出流 2.RandomAccessFile
try (FileChannel channel = new FileInputStream("Data.txt").getChannel()) {
    // 准备缓冲区
    ByteBuffer buffer = ByteBuffer.allocate(10);
    while (true) {
        // 从 channel 读娶数据,写入buffer
        int len = channel.read(buffer); // read 方法是阻塞方法,如果没读取到数据,会阻塞在这里
        if (len == -1) {
            break;
        }
        //切换buffer为读模式
        buffer.flip();
        // 打印buffer内容
        while (buffer.hasRemaining()) { // buffer.hasRemaining() 检擦是否还有剩余数据
            byte b = buffer.get();  // get() 每次读一个字符,会移动读指针 position;相比较,get(i)则不会移动读指针 position;而 get(new byte[n]) 则会读取 n 个字符,并且移动 position
            System.out.print((char)b);
        }
        // 切换成写模式,方法一
        buffer.clear();
        /*
           切换成写模式,方法二:compact();
      此方法会将未读取的字符前移,将 position 重置到可写入的下标位置。   例如5个字符,读取了2个,还有3个,调用该法则会将剩余3个字符前移,position定位到下标为3的位置
*/ //buffer.compact();
     //buffer.rewind(); // 从头开始读,本质是将 position 设为 0
} } catch (IOException e) { e.printStackTrace(); }

 

 

三、ByteBuffer与字符串互转

1)字符串转ByteBuffer

// 方法一
ByteBuffer buff1 = ByteBuffer.allocate(16);
buff1.put("hello".getBytes(StandardCharsets.UTF_8));

// 方法二,会将ByteBuffer切换成读模式
ByteBuffer buff2 = StandardCharsets.UTF_8.encode("hello");

// 方法三,会将ByteBuffer切换成读模式
ByteBuffer buff3 = ByteBuffer.wrap("hello".getBytes(StandardCharsets.UTF_8));

// 方法四
ByteBuffer buff4 = Charset.defaultCharset().encode("hello");

2)ByteBuffer转字符串(被转换的ByteBuffer必须处于读模式

// 方法一
String str = StandardCharsets.UTF_8.decode(buff2).toString();

// 方法二
String str = buff2.toString();

// 方法三
String str = Charset.defaultCharset().decode(buff2).toString();

 

posted @ 2021-07-12 21:55    阅读(171)  评论(0编辑  收藏  举报