Netty 中使用 ByteBuf 代替 Java NIO 提供的 ByteBuffer 作为字节的容器。

一、索引

  ByteBuf 提供两个指针变量支持读和写操作,读操作使用 readerIndex,写操作使用 writerIndex。如下图:

  

  1. 可丢弃字节,因为它们已经被读
  2. 可读字节,已写入但还没有被读取
  3. 可写字节

二、索引管理

  1. 调用 markReaderIndex(), markWriterIndex(), resetReaderIndex() 和 resetWriterIndex() 来设置和重新定位 readerIndex 和 writerIndex,
  2. 调用 readerIndex(int) 或 writerIndex(int) 将指针移动到指定的位置
  3. 调用 clear() 同时设置 readerIndex 和 writerIndex 为 0

三、查询操作

  可以使用以 ByteBufProcessor 为参数的方法,下面例子实现了寻找一个回车符( \r ):

 ByteBuf in = (ByteBuf)msg;
int index = in.forEachByte(ByteProcessor.FIND_CR);

四、衍生的缓冲区

  slice 方法和 copy 方法都能实现拷贝功能,但是它们有不同之处,下面两个例子说明了它们的不同之处。

  先看看 slice 的例子:

 Charset utf8 = Charset.forName("UTF-8");
ByteBuf buf = Unpooled.copiedBuffer("Netty in Action rocks!", utf8); ByteBuf sliced = buf.slice(0, 14); // 创建从0开始到14的新slice
System.out.println(sliced.toString(utf8)); //打印 Netty in Action buf.setByte(0, (byte) 'J'); //更新索引为0的字节
// 断言成功,说明slice之后两段数据共享
assert buf.getByte(0) == sliced.getByte(0);

  这个说明 slice 返回的是原缓冲区的一个副本,共享同一片数据。因此若需要操作某段数据,使用 slice 方法。

  下面来看看 copy 方法是如何不同的:

 Charset utf8 = Charset.forName("UTF-8");
ByteBuf buf = Unpooled.copiedBuffer("Netty in Action rocks!", utf8); ByteBuf copy = buf.copy(0, 14); // 注意这里使用了copy
System.out.println(copy.toString(utf8)); buf.setByte(0, (byte) 'J');
// 断言成功,说明原数据修改对copy不影响
assert buf.getByte(0) != copy.getByte(0);

  可以看到,代码几乎是相同的,但所衍生的 ByteBuf 效果是不同的。

五、读 / 写操作

  读 / 写操作主要有两类:

  • get() / set() 操作:从给定的索引开始,写索引和读索引保持不变
  • read() / write() 操作:从给定的索引开始,根据字节访问的数量,递增当前的写索引或读索引。  

  需要特别注意上述两类操作对于读索引和写索引的影响。

  常见的 get() 操作如下:

  

  常见的 set() 操作如下:

  

  常见的 read() 操作如下:

  

  每个 read() 方法都对应一个 write() 方法,如下:

  

六、更多操作  

  还有一些比较常用的方法如下:

  

Netty入门(四)ByteBuf 字节级别的操作的更多相关文章

  1. 网络编程Netty入门:ByteBuf分析

    目录 Netty中的ByteBuf优势 NIO使用的ByteBuffer有哪些缺点 ByteBuf的优势和做了哪些增强 ByteBuf操作示例 ByteBuf操作 简单的Demo示例 堆内和堆外内存 ...

  2. 数据库操作事物的四大特性以及MySQL数据库的四种隔离级别

    1 .事物操作数据库的四大特性(ACID) 1.原子性 (Atomicity) 原子性:就是事物的所包含的所有操作,要么全部成功,要么全部失败回滚. 2.一致性 (Consistency) 一致性:简 ...

  3. Netty入门与实战教程总结分享

    前言:都说Netty是Java程序员必须要掌握的一项技能,带着不止要知其然还要知其所以然的目的,在慕课上找了一个学习Netty源码的教程,看了几章后着实有点懵逼.虽然用过Netty,并且在自己的个人网 ...

  4. Netty入门

    一.NIO Netty框架底层是对NIO的高度封装,所以想要更好的学习Netty之前,应先了解下什么是NIO - NIO是non-blocking的简称,在jdk1.4 里提供的新api,他的他的特性 ...

  5. netty入门(一)

    1. netty入门(一) 1.1. 传统socket编程 在任何时候都可能有大量的线程处于休眠状态,只是等待输入或者输出数据就绪,这可能算是一种资源浪费. 需要为每个线程的调用栈都分配内存,其默认值 ...

  6. Netty入门教程——认识Netty

    什么是Netty? Netty 是一个利用 Java 的高级网络的能力,隐藏其背后的复杂性而提供一个易于使用的 API 的客户端/服务器框架. Netty 是一个广泛使用的 Java 网络编程框架(N ...

  7. Java网络编程 -- Netty入门

    Netty简介 Netty是一个高性能,高可扩展性的异步事件驱动的网络应用程序框架,它极大的简化了TCP和UDP客户端和服务器端网络开发.它是一个NIO框架,对Java NIO进行了良好的封装.作为一 ...

  8. Netty入门(1) - 简介

    什么是Netty? Netty 是一个利用 Java 的高级网络的能力,隐藏其背后的复杂性而提供一个易于使用的 API 的客户端/服务器框架. Tomcat和Netty有什么区别? Netty和Tom ...

  9. Netty入门1之----认识Netty

      Netty 什么是Netty? Netty 是一个利用 Java 的高级网络的能力,隐藏其背后的复杂性而提供一个易于使用的 API 的客户端/服务器框架. Netty 是一个广泛使用的 Java ...

随机推荐

  1. C++中的 CONST 含义(从#define 到 CONST 的转变)

    const 与define 两者都可以用来定义常量,但是const定义时,定义了常量的类型,所以更精确一些.#define只是简单的文本替换,除了可以定义常量外,还可以用来定义一些简单的函数,有点类似 ...

  2. java多线程——线程池源码分析(一)

    本文首发于cdream的个人博客,点击获得更好的阅读体验! 欢迎转载,转载请注明出处. 通常应用多线程技术时,我们并不会直接创建一个线程,因为系统启动一个新线程的成本是比较高的,涉及与操作系统的交互, ...

  3. Zipper(poj2192)dfs+剪枝

    Zipper Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 15277   Accepted: 5393 Descripti ...

  4. 2.Observer Pattern(观察者模式)

    Observer Pattern(观察者模式)定义: 在对象之间定义一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象都会收到通知,并自动更新. 干说定义肯定没有举例理解的透彻.想到Observ ...

  5. python生成器简单了解

    1.什么是生成器 通过列表生成式,我们可以直接创建一个列表.但是,受到内存限制,列表容量肯定是有限的.而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素, ...

  6. CentOS 修改用户密码

    CentOS 修改用户密码 1.普通用户 ①获取超级用户root权限 命令:su 或者 su- 或者 su -root ②输入命令: passwd 用户名 ③输入新密码 2.超级用户 ①打开syste ...

  7. python中matplotlib.pyplot中cm的属性

    https://matplotlib.org/gallery/color/colormap_reference.html

  8. 记录Ubuntu 16.04 安装Docker CE

    一.Docker的两个版本 Docker有两个版本: 社区版(CE) 企业版(EE) Docker Community Edition(CE)非常适合希望开始使用Docker并尝试使用基于容器的应用程 ...

  9. 【已解决】mac上appium报错:“Could not find aapt Please set the ANDROID_HOME environment variable with the Android SDK root directory path”

    按照网上教程配置完appium环境后,真机跑自动化过程,遇到如下报错: appium报错如下: [ADB] Checking whether aapt is present [ADB] The AND ...

  10. sql Server 查询方法的优化

    在使用SQL语句查询数据库记录时,如果要查询相同的内容,有着不同的多种方法. 仍然,尽管使用多种方法可以得到相同的结果,但是,如果您使用不同的方法,在执行效益上是截然不同的.因此,我们得仔细考虑,如果 ...