Netty Review - ByteBuf 读写索引 详解

文章目录

  • 概念
  • Pre
  • 概述
  • ByteBuf简介
  • ByteBuf的主要特性
  • 结构
  • API
    • ByteBuf的创建
    • 读写操作示例
    • 引用计数操作
    • 其他常用操作
  • Code 演示

在这里插入图片描述


概念

在这里插入图片描述


Pre

Netty Review - 探索ByteBuf的内部机制


概述

Netty的ByteBuf是一个强大的字节容器,用于处理字节数据。它提供了比Java标准库中的ByteBuffer更灵活和高效的方式来操作字节数据。


ByteBuf简介

Netty的ByteBuf是一个字节容器,它提供了一种更灵活和高效的方式来操作字节数据。与ByteBuffer不同,ByteBuf具有可扩展的缓冲区,可以动态调整容量,而不需要创建新的缓冲区对象。


ByteBuf的主要特性

  • 可读性和可写性: ByteBuf具有读和写两种模式。读操作和写操作是相互独立的,因此可以在不同的操作中使用同一段数据。
  • 零拷贝: ByteBuf支持零拷贝操作,这意味着可以直接操作底层内存,而无需将数据复制到中间缓冲区。
  • 引用计数: ByteBuf使用引用计数来跟踪对缓冲区的活动引用,这有助于防止内存泄漏。

结构

ByteBuf有三个关键的指针,分别是readerIndex、writerIndex和capacity。

  • readerIndex表示读操作的起始位置,
  • writerIndex表示写操作的起始位置,
  • capacity表示ByteBuf的容量

在这里插入图片描述

  • 从结构上来说,ByteBuf 由一串字节数组构成。数组中每个字节用来存放信息。

  • ByteBuf 提供了两个索引,一个用于读取数据,一个用于写入数据。这两个索引通过在字节数组中移动,来定位需要读或者写信息的位置。

    读写操作: 通过readerIndex和writerIndex来进行读写操作,支持顺序读写和随机读写

  • 当从 ByteBuf 读取时,它的 readerIndex(读索引)将会根据读取的字节数递增。

  • 同样,当写 ByteBuf 时,它的 writerIndex 也会根据写入的字节数进行递增。

  • 需要注意的是极限的情况是 readerIndex 刚好读到了 writerIndex 写入的地方。 如果 readerIndex 超过了 writerIndex 的时候,Netty 会抛出 IndexOutOf-BoundsException 异常。


API

ByteBuf的创建

ByteBuf buffer = Unpooled.buffer(10);  // 创建一个初始容量为10的ByteBuf

读写操作示例

// 写入数据
buffer.writeBytes("Hello".getBytes());// 读取数据
byte[] data = new byte[buffer.readableBytes()];
buffer.readBytes(data);
System.out.println(new String(data));

引用计数操作

// 引用计数 +1
buffer.retain();// 引用计数 -1,如果引用计数为0,则释放相关资源
buffer.release();

其他常用操作

  • 获取和设置索引位置的字节值。
  • 查找指定字节或字节数组的位置。
  • 派发读/写索引而不实际移动数据。

Code 演示


import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.util.CharsetUtil;public class NettyByteBuf {public static void main(String[] args) {// 创建byteBuf对象,该对象内部包含一个字节数组byte[14]// 通过readerindex和writerIndex和capacity,将buffer分成三个区域// 已经读取的区域:[0,readerindex)// 可读取的区域:[readerindex,writerIndex)// 可写的区域: [writerIndex,capacity)ByteBuf byteBuf = Unpooled.buffer(14);System.out.println("byteBuf=" + byteBuf);printBytebuf(byteBuf);System.out.println("=================");for (int i = 0; i < 8; i++) {byteBuf.writeByte(i);}System.out.println("byteBuf=" + byteBuf);printBytebuf(byteBuf);System.out.println("=================");for (int i = 0; i < 5; i++) {System.out.println(byteBuf.getByte(i));}System.out.println("byteBuf=" + byteBuf);printBytebuf(byteBuf);System.out.println("=================");for (int i = 0; i < 5; i++) {System.out.println(byteBuf.readByte());}System.out.println("byteBuf=" + byteBuf);printBytebuf(byteBuf);System.out.println("=================");//用Unpooled工具类创建ByteBufString text = "hello,artisan!" ;ByteBuf byteBuf2 = Unpooled.copiedBuffer(text , CharsetUtil.UTF_8);//使用相关的方法if (byteBuf2.hasArray()) {byte[] content = byteBuf2.array();//将 content 转成字符串System.out.println(new String(content, CharsetUtil.UTF_8));System.out.println("byteBuf2=" + byteBuf2);printBytebuf(byteBuf2);System.out.println("=================");// 获取数组0这个位置的字符h的ascii码,h=104System.out.println(byteBuf2.getByte(0));System.out.println("=================");//可读的字节数  14int len = byteBuf2.readableBytes();System.out.println("len=" + len);printBytebuf(byteBuf2);System.out.println("=================");//使用for取出各个字节for (int i = 0; i < len; i++) {System.out.println((char) byteBuf2.getByte(i));}printBytebuf(byteBuf2);System.out.println("=================");//范围读取System.out.println(byteBuf2.getCharSequence(0, 6, CharsetUtil.UTF_8));printBytebuf(byteBuf2);System.out.println("=================");System.out.println(byteBuf2.getCharSequence(6, 8, CharsetUtil.UTF_8));printBytebuf(byteBuf2);}}public static void printBytebuf(ByteBuf byteBuf){System.out.println("readerIndex:" + byteBuf.readerIndex());System.out.println("writerIndex:" + byteBuf.writerIndex());System.out.println("capacity:" + byteBuf.capacity());}
}

输出

byteBuf=UnpooledByteBufAllocator$InstrumentedUnpooledUnsafeHeapByteBuf(ridx: 0, widx: 0, cap: 14)
readerIndex:0
writerIndex:0
capacity:14
=================
byteBuf=UnpooledByteBufAllocator$InstrumentedUnpooledUnsafeHeapByteBuf(ridx: 0, widx: 8, cap: 14)
readerIndex:0
writerIndex:8
capacity:14
=================
0
1
2
3
4
byteBuf=UnpooledByteBufAllocator$InstrumentedUnpooledUnsafeHeapByteBuf(ridx: 0, widx: 8, cap: 14)
readerIndex:0
writerIndex:8
capacity:14
=================
0
1
2
3
4
byteBuf=UnpooledByteBufAllocator$InstrumentedUnpooledUnsafeHeapByteBuf(ridx: 5, widx: 8, cap: 14)
readerIndex:5
writerIndex:8
capacity:14
=================
hello,artisan!                            
byteBuf2=UnpooledByteBufAllocator$InstrumentedUnpooledUnsafeHeapByteBuf(ridx: 0, widx: 14, cap: 42)
readerIndex:0
writerIndex:14
capacity:42
=================
104
=================
len=14
readerIndex:0
writerIndex:14
capacity:42
=================
h
e
l
l
o
,
a
r
t
i
s
a
n
!
readerIndex:0
writerIndex:14
capacity:42
=================
hello,
readerIndex:0
writerIndex:14
capacity:42
=================
artisan!
readerIndex:0
writerIndex:14
capacity:42

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/235214.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

DAY11

问题一&#xff1a;指针与引用的区别 疑问 为什么引用的本质是指针常量&#xff0c;但是对它求sizeof却是变量所占内存空间的大小那&#xff1f;&#xff1f;&#xff1f;&#xff1f;&#xff1f;&#xff1f;&#xff1f;&#xff1f;&#xff1f;&#xff1f; 1.引用是给变…

llvm后端之DAG设计

llvm后端之DAG设计 引言1 核心类设计2 类型系统2.1 MVT::SimpleValueType2.2 MVT2.3 EVT 3 节点类型 引言 llvm后端将中端的IR转为有向无环图&#xff0c;即DAG。如下图&#xff1a; 图中黑色箭头为数据依赖&#xff1b;蓝色线和红色线为控制依赖。蓝色表示指令序列化时两个节…

【教3妹学编程-算法题】循环移位后的矩阵相似检查

插&#xff1a; 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 坚持不懈&#xff0c;越努力越幸运&#xff0c;大家一起学习鸭~~~ 3妹&#xff1a;“太阳当空照&#xff0c;花儿对我笑&…

干货!什么是财务业务化和业务财务化?

此回答摘录自《自价值财务&#xff1a;以业务与财务的双向奔赴&#xff0c;成就合规与增长双赢》&#xff0c;原文近7000字&#xff0c;作者纷享销客CFO郭保彬先生。更多业财一体化内容详见纷享销客最新专刊《上市公司如何打好合规与增长双赢之战》。 如今&#xff0c;财务管理…

Linux系统配置与服务管理基础(二)

目录 一、通配符 1. 简介 2. 作用 3. 符号与效果 4. 示例 二、别名alias 1. 语法选项 2. 示例 3. 补充说明 三、查看磁盘使用量 1. 语法选项 2. ll与du区别 3. 补充 四、创建目录mkdir 1. 语法选项 2. 示例 四、建立空文件touch 1. 语法选项 2. 附加功能 3…

【Kotlin】基础变量、集合和安全操作符

文章目录 数字字面常量显式转换数值类型转换背后 位运算符字符串字符串模板修饰符数组集合&#xff08;Kotlin自带&#xff09;通过序列提高效率惰性求值序列的操作方式中间操作末端操作 可null类型安全调用操作符 ?.操作符 ?:非空断言操作符 !! 使用类型检测及自动类型转换安…

第二百一十七回 修改页面导航中遇到的问题

文章目录 1. 问题介绍2. 使用方法3. 代码与分析3.1 示例代码3.2 代码分析4. 内容总结我们在上一章回中介绍了"分享一种更新页面数据的方法"相关的内容,本章回中将介绍修改页面导航中遇到的问题.闲话休提,让我们一起Talk Flutter吧。 1. 问题介绍 我们在页面之间导…

uni-app获取指定时间为周几,日期格式化为 “YYYY-MM-DD“ 的形式

在 uni-app 中&#xff0c;你可以使用 JavaScript 的 Date 对象来获取指定时间是星期几。以下是一个简单的示例代码&#xff0c;演示了如何在 uni-app 中实现这一功能&#xff1a; // 假设有一个指定的日期时间 const specifiedDate new Date(2023-12-25);// 获取这个指定日期…

go学习笔记

指针使用 // Person 定义一个人的结构体 type Person struct {// 姓名Name string// 年龄Age int// 性别Sex string// 身份证号idNumber string }//1、声明一个结构体变量var person Personfmt.Println(person.Name) // ""fmt.Println(person.Age) // 0fmt…

学习——html基础

什么是HTML Hyper Text Markup Language (超文本标记语言) 标记又俗称标签(tag)&#xff0c;一般格式&#xff1a; 如 <h1></h1>标签里还可以有属性(Attribute)&#xff1a; <tagName Atrribute “value" /> 如 <meta charset"utf-8"…

selenium自动化webdriver下载及安装

1、确认浏览器的版本 在浏览器的地址栏&#xff0c;输入chrome://version/&#xff0c;回车后即可查看到对应版本 2、找到对应的chromedriver版本 2.1 114及之前的版本可以通过点击下载chromedriver,根据版本号&#xff08;只看大版本&#xff09;下载对应文件 2.2 116版本通过…

【进阶篇】YOLOv8实现K折交叉验证——解决数据集样本稀少和类别不平衡的难题,让你的模型评估更加稳健

YOLOv8专栏导航&#xff1a;点击此处跳转 K折交叉验证 K折交叉验证&#xff08;K-Fold Cross-Validation&#xff09;是一种常用的机器学习模型评估方法&#xff0c;可以帮助我们评估模型的性能&#xff0c;特别适用于数据集相对较小的情况。 在K折交叉验证中&#xff0c;将原…

redis相关面试题

1、说一说你在项目中的redis的应用场景&#xff1f; 需要频繁查询的数据&#xff0c;分布式锁&#xff0c;spring session 5大value类型&#xff1a;string hash list set zset基本上就是缓存为的是服务无状态&#xff0c;延申思考&#xff0c;看你的项目有哪些数据结构或对象…

springboot 整合 springdataJPA 自定义操作 JPQL和SQL

1.接口StudentJPQLSQLMapper.java package com.jmj.springDataApp.mapper;import com.jmj.springDataApp.pojo.Student; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.da…

final的详解

在Java中&#xff0c;final 关键字用于表示不可改变的实体&#xff0c;可以应用于变量、方法、类和指令重排序。它有不同的作用&#xff0c;具体取决于它被应用的上下文。 1.对于变量&#xff1a; 如果一个变量被声明为 final&#xff0c;则该变量的值在一旦被赋予后就不能再被…

Starting the Docker Engine...一直转圈

出现的问题&#xff1a; 原因排查&#xff1a; 看了网上的很多篇文章&#xff0c;每个原因都排查了&#xff0c;没有发现问题。 遇到这样的情况应先看自己是否安装成功 打开运行&#xff0c;在空框中输入powershell并点击确定&#xff1a; docker version 显示版本证明安装…

3. 控制流程

3. 控制流程 ​ 跟任何的程序设计语言一样&#xff0c;Java使用条件语句和循环结构确定控制流程。 3.1 块作用域 ​ 块是指由一对大括号括起来的若干条简单的Java语句&#xff0c;块确定了变量的作用域。一个块可以嵌套在另一个块中。 常见例子&#xff1a; public static v…

微信小程序-选择和分割打开地图选择位置的信息

一、 前言 废话不多说&#xff0c;单刀直入。 本文要实现的功能是微信小程序中打开地图选择位置&#xff0c;以及将返回的位置信息分割。 例如返回的位置信息是&#xff1a;广东省深圳市龙岗区xxxxx小区 分割后变成&#xff1a; {province: "广东省",city: "深…

前端技术基建过程

1. 技术基建: 是研发团队的技术基础设施建设,是一个团队通用的技术能力沉淀. (1). 业务、架构、基建理解: ①. 业务支撑是活在当下②. 技术基建是活在未来(2). 意义: ①. 技术的价值在于解决业务问题,"业务支撑"和"基础建设"都是为了帮助业务解决问题②.…

042.Python异常处理_异常捕获

我 的 个 人 主 页&#xff1a;&#x1f449;&#x1f449; 失心疯的个人主页 &#x1f448;&#x1f448; 入 门 教 程 推 荐 &#xff1a;&#x1f449;&#x1f449; Python零基础入门教程合集 &#x1f448;&#x1f448; 虚 拟 环 境 搭 建 &#xff1a;&#x1f449;&…