JDK-In-Action-NIO-ByteBuffer

ByteBuffer

ByteBuffer用于NIO的可以在堆内存中分配或者直接内存中分配的缓冲区实现,有8中具体的类型.
ByteBuffer具有三个核心属性:

  • capacity : 缓冲区容量
  • limit : 读写限制索引
  • position : 读写开始索引
    通过操纵 limit 和 position 两个索引,来对缓冲区进行读写,具体参见下文API示例.

API 示例

Buffer的三个重要属性

 ByteBuffer buffer = ByteBuffer.allocate(8);
 //初始属性
 assertEquals(buffer.capacity(), 8);
 assertEquals(buffer.limit(), 8);
 assertEquals(buffer.position(), 0);
 //写入数据后属性
 buffer.putInt(10);
 assertEquals(buffer.capacity(), 8);
 assertEquals(buffer.limit(), 8);
 assertEquals(buffer.position(), 4);
 //翻转为读模式
 buffer.flip();
 assertEquals(buffer.capacity(), 8);
 assertEquals(buffer.limit(), 4);
 assertEquals(buffer.position(), 0);
 //读数据后属性
 buffer.getInt();
 assertEquals(buffer.capacity(), 8);
 assertEquals(buffer.limit(), 4);
 assertEquals(buffer.position(), 4);
 //清空数据后属性
 buffer.clear();
 assertEquals(buffer.capacity(), 8);
 assertEquals(buffer.limit(), 8);
 assertEquals(buffer.position(), 0);

Buffer管理之 Clear与 Compact

 ByteBuffer buffer = ByteBuffer.allocate(12);
 buffer.putInt(8);

 //重置索引值,不会直接操作数据
 buffer.clear();
 assertEquals(buffer.capacity(), 12);
 assertEquals(buffer.limit(), 12);
 assertEquals(buffer.position(), 0);

 buffer.putInt(8);
 buffer.flip();
 int i = buffer.getInt();
 assertEquals(i, 8);

 //丢弃已读数据,拷贝buffer覆盖已读数据
 buffer.compact();
 assertEquals(buffer.capacity(), 12);
 assertEquals(buffer.limit(), 12);
 assertEquals(buffer.position(), 0);
 buffer.putInt(8);

Buffer管理之 Mark与 Reset

 ByteBuffer buffer = ByteBuffer.allocate(12);
 buffer.putInt(8);
 buffer.putInt(9);
 //标记position位置
 buffer.mark();
 buffer.putInt(10);
 //还原position位置
 buffer.reset();
 //读position之后的数据
 int i = buffer.getInt();
 assertEquals(i, 10);

Buffer重复 Rewind

 CharBuffer buffer = CharBuffer.wrap(new char[]{'1', '2', '3'});
 char c = buffer.get();
 assertEquals(c, '1');
 c = buffer.get();
 assertEquals(c, '2');
 buffer.rewind();
 char cc = buffer.get();
 assertEquals(cc, '1');

Jdk Nio分开读 Scatter与聚合写 Gather

 try {
     File tempFile = File.createTempFile("test", ".txt");
     FileChannel channel = FileChannel.open(tempFile.toPath(), StandardOpenOption.WRITE);
     ByteBuffer header = ByteBuffer.wrap("Header".getBytes());
     ByteBuffer body = ByteBuffer.wrap("Body".getBytes());

     //Gather
     channel.write(new ByteBuffer[]{header, body});
     channel.close();

     channel = FileChannel.open(tempFile.toPath(), StandardOpenOption.READ);
     ByteBuffer h = ByteBuffer.allocate(header.capacity());
     ByteBuffer b = ByteBuffer.allocate(body.capacity());

     //Scatter
     channel.read(new ByteBuffer[]{h, b});
     channel.close();

     assertEquals(header, h);
     assertEquals(body, b);

 } catch (IOException e) {
     e.printStackTrace();
 }

NIO的8种 Buffer类型

 ByteBuffer byteBuffer = ByteBuffer.allocate(1);
 ByteBuffer buffer = MappedByteBuffer.allocateDirect(1);
 CharBuffer charBuffer = CharBuffer.wrap(new char[]{1});
 ShortBuffer shortBuffer = ShortBuffer.allocate(2);
 IntBuffer intBuffer = IntBuffer.wrap(new int[]{1});
 LongBuffer longBuffer = LongBuffer.allocate(8);
 FloatBuffer floatBuffer = FloatBuffer.allocate(4);
 DoubleBuffer doubleBuffer = DoubleBuffer.allocate(8);

分配堆内存缓冲区

 ByteBuffer buffer = ByteBuffer.allocate(4);
 assertEquals(buffer.isDirect(), false);

分配直接内存缓冲区

 ByteBuffer buffer = ByteBuffer.allocateDirect(4);
 assertEquals(buffer.isDirect(), true);

缓冲区读写基本步骤

 ByteBuffer buffer = ByteBuffer.allocate(4);
 //写入数据
 buffer.putInt(10);
 //翻转
 buffer.flip();
 //读数据
 int v = buffer.getInt();
 //清理
 buffer.clear();
 assertEquals(v, 10);

读文件数据到 Buffer

 try {
     File resource = new File(SRC_ROOT_DIR, ByteBufferExample.class.getCanonicalName().replaceAll("\\.", "/") + ".java");
     FileChannel fileChannel = FileChannel.open(resource.toPath(), StandardOpenOption.READ);
     ByteBuffer buffer = ByteBuffer.allocate(128);
     fileChannel.read(buffer);
     fileChannel.close();
     System.out.println(new String(buffer.array()));
     buffer.clear();
 } catch (IOException e) {
     e.printStackTrace();
 }
package com.gitee.zhwcong.nio;

import com.gitee.zhwcong.Example;

import javax.print.DocFlavor;
import java.io.File;
impo

引用

posted @ 2020-05-05 22:19  onion94  阅读(193)  评论(0编辑  收藏  举报