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();