文档章节

Netty进阶基础篇之NIO Buffer篇(3)

木九天
 木九天
发布于 07/13 23:55
字数 980
阅读 32
收藏 0

1、Buffer概念

1.1 缓冲区获取

Buffer缓冲区是就是一个数组,有着不同的数据类型:ByteBuffer、CharBuffer、ShortBuffer、IntBuffer、LongBuffer、FloatBuffer、DoubleBuffer,然后这些数据类型都可以通过 allocate() 获取缓冲区。

static XxxBuffer allocate(int capacity) : 创建一个容量为 capacity 的 XxxBuffer 对象,如下:

//1. 分配一个指定大小的Byte类型的缓冲区
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);

1.2  缓冲区存取数据的两个核心方法

put() : 存入数据到缓冲区中

put方法
put(byte b) 将给定单个字节写入缓冲区的当前位置

put(byte[] src)

将 src 中的字节写入缓冲区的当前位置

put(int index, byte b)

将指定字节写入缓冲区的索引位置(不会移动 position)


get() : 获取缓冲区中的数据

get方法

get()

读取单个字节

get(byte[] dst)

批量读取多个字节到 dst 中

get(int index)

读取指定索引位置的字节(不会移动 position)

byteBuffer.put(“Mujiutian”);
byteBuffer.get();

1.3 缓冲区中的四个核心属性

0 <= mark <= position <= limit <= capacity

capacity : 容量,表示缓冲区中最大存储数据的容量。一旦声明不能改变。

byteBuffer.capacity()

limit : 界限,表示缓冲区中可以操作数据的大小。(limit 后数据不能进行读写)

byteBuffer.limit()

position : 位置,表示缓冲区中正在操作数据的位置。

byteBuffer.position()

mark : 标记,表示记录当前 position 的位置。可以通过 reset() 恢复到 mark 的位置

byteBuffer.mark()

1.4 Buffer常用的方法

1.5、直接缓冲区与非直接缓冲区

非直接缓冲区:通过 allocate() 方法分配缓冲区,将缓冲区建立在 JVM 的内存中

直接缓冲区:通过 allocateDirect() 方法分配直接缓冲区,将缓冲区建立在物理内存中。可以提高效率

2、代码讲解

2.1 使用缓冲区的各种方法

@Test
public void test1(){
   String str = "MuJiuTian";
   
   //1. 分配一个指定大小的Byte类型的缓冲区
   ByteBuffer buf = ByteBuffer.allocate(1024);
   
   System.out.println("-----------------allocate()----------------");
   //此时缓冲区为读,下标位置
   System.out.println(buf.position());
   //此时缓冲区的界线,也就是临界点,1024
   System.out.println(buf.limit());
   //缓冲区的容量
   System.out.println(buf.capacity());
   
   //2. 利用 put() 存入数据到缓冲区中
   buf.put(str.getBytes());
   
   System.out.println("-----------------put()----------------");
   //此时缓冲区为读,下标位置已经读到第五个了
   System.out.println(buf.position());
   System.out.println(buf.limit());
   System.out.println(buf.capacity());
   
   //3. 切换读取数据模式,切换为写的模式,也就是把刚刚读取的内容重新从下标0开始读
   buf.flip();
   
   System.out.println("-----------------flip()----------------");
   System.out.println(buf.position());
   System.out.println(buf.limit());
   System.out.println(buf.capacity());
   
   //4. 利用 get() 读取缓冲区中的数据
   byte[] dst = new byte[buf.limit()];
   buf.get(dst);
   System.out.println(new String(dst, 0, dst.length));
   
   System.out.println("-----------------get()----------------");
   System.out.println(buf.position());
   System.out.println(buf.limit());
   System.out.println(buf.capacity());
   
   //5. rewind() : 可重复读
   buf.rewind();
   
   System.out.println("-----------------rewind()----------------");
   System.out.println(buf.position());
   System.out.println(buf.limit());
   System.out.println(buf.capacity());
   
   //6. clear() : 清空缓冲区. 但是缓冲区中的数据依然存在,但是处于“被遗忘”状态
   buf.clear();
   
   System.out.println("-----------------clear()----------------");
   System.out.println(buf.position());
   System.out.println(buf.limit());
   System.out.println(buf.capacity());
   
   System.out.println((char)buf.get());
}

结果:

看刚刚的流程图:

2.2 使用简单方法掌握buffer的基本方法

@Test
public void test2(){

   String str = "Mujiutian";

   //创建Byte类型缓冲区
   ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
   //此时为读模式,读取str内容
   byteBuffer.put(str.getBytes());
   //切换为写的模式,处理刚刚读取的内容
   byteBuffer.flip();

   //此时limit为9,因为读取了Mujiutian 9个字节
   byte[] dst = new byte[byteBuffer.limit()];
   //读取下标0到2的字节
   byteBuffer.get(dst, 0, 2);
   System.out.println(new String(dst, 0, 2));
   System.out.println(byteBuffer.position());
   
   //mark() : 标记
   byteBuffer.mark();

   byteBuffer.get(dst, 2, 2);
   System.out.println(new String(dst, 2, 2));
   System.out.println(byteBuffer.position());
   
   //reset() : 使用该方法,位置恢复到 mark 的位置
   byteBuffer.reset();
   System.out.println(byteBuffer.position());
   
   //判断缓冲区中是否还有剩余数据
   if(byteBuffer.hasRemaining()){
      //获取缓冲区中可以操作的数量
      System.out.println(byteBuffer.remaining());
   }
}

结果为:

2.3 测试是否为缓冲区

@Test
public void test3(){
   //分配直接缓冲区
   ByteBuffer buf = ByteBuffer.allocateDirect(1024);
   System.out.println(buf.isDirect());
}

结果:true

© 著作权归作者所有

木九天

木九天

粉丝 178
博文 224
码字总数 170732
作品 0
海淀
程序员
私信 提问
Netty进阶基础篇之流概念篇(1)

序言:学Netty之前,对流的概念应该深刻一些,所以先理解一下流的使用! 1、IO、NIO、AIO 含义区别 1.1 同步阻塞I/O(BIO block io) jdk1.4之前就一个io流,服务器实现模式为一个连接一个线程...

木九天
07/13
32
0
少啰嗦!一分钟带你读懂Java的NIO和经典IO的区别

本文引用了“架构师社区”公众号的《史上讲的最好的Java NIO与IO的区别与应用》一文部分内容,感谢原作者的技术分享。 1、引言 很多初涉网络编程的程序员,在研究Java NIO(即异步IO)和经典...

JackJiang2011
06/25
0
0
Netty进阶基础篇之NIO 阻塞通信(5)

NIO 完成网络通信的三个核心:Channel、Buffer、Selector 1、通道(Channel) 负责连接 SocketChannel、ServerSocketChannel、DatagramChannel、Pipe.SinkChannel、Pipe.SourceChannel 2、缓......

木九天
07/14
13
0
NIO相关基础篇二

转载请注明原创出处,谢谢! 上篇NIO相关基础篇一,主要介绍了一些基本的概念以及缓冲区(Buffer)和通道(Channel),本篇继续NIO相关话题内容,主要就是文件锁、以及比较关键的Selector,后...

匠心零度
2017/12/18
0
0
Netty精粹之JAVA NIO开发需要知道的

学习Netty框架以及相关源码也有一小段时间了,恰逢今天除夕,写篇文章总结一下。Netty是个高效的JAVA NIO框架,总体框架基于异步非阻塞的设计,基于网络IO事件驱动,主要贡献在于可以让用户基...

Float_Luuu
2016/02/07
14.8K
3

没有更多内容

加载失败,请刷新页面

加载更多

最简单的获取相机拍照的图片

  import android.content.Intent;import android.graphics.Bitmap;import android.os.Bundle;import android.os.Environment;import android.provider.MediaStore;import andr......

MrLins
27分钟前
4
0
说好不哭!数据可视化深度干货,前端开发下一个涨薪点在这里~

随着互联网在各行各业的影响不断深入,数据规模越来越大,各企业也越来越重视数据的价值。作为一家专业的数据智能公司,个推从消息推送服务起家,经过多年的持续耕耘,积累沉淀了海量数据,在...

个推
29分钟前
7
0
第三方支付-返回与回调注意事项

不管是支付宝,微信,还是其它第三方支付,第四方支付,支付机构服务商只要涉及到钱的交易都要进行如下校验,全部成功了才视为成功订单 1.http请求是否成功 2.校验商户号 3.校验订单号及状态...

Shingfi
32分钟前
4
0
简述Java内存分配和回收策略以及Minor GC 和 Major GC(Full GC)

内存分配: 1. 栈区:栈可分为Java虚拟机和本地方法栈 2. 堆区:堆被所有线程共享,在虚拟机启动时创建,是唯一的目的是存放对象实例,是gc的主要区域。通常可分为两个区块年轻代和年老代。更...

DustinChan
38分钟前
6
0
Excel插入批注:可在批注插入文字、形状、图片

1.批注一直显示:审阅选项卡-------->勾选显示批注选项: 2.插入批注快捷键:Shift+F2 组合键 3.在批注中插入图片:鼠标右键点击批注框的小圆点【重点不可以在批注文本框内点击】----->调出批...

东方墨天
今天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部