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;财务管理…

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

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

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

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

学习——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;看你的项目有哪些数据结构或对象…

final的详解

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

Starting the Docker Engine...一直转圈

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

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

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

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

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

SpringBoot前后端分离开发项目部署时,项目打包准备工作

第一步&#xff1a;项目打包之前&#xff0c;拉前后端代码 拉完代码后&#xff0c;再执行下面操作&#xff08;确保项目能正常启动并运行&#xff09; 后端&#xff08;执行如下操作&#xff09; mvn clean install -T 8 -Dmaven.test.skiptrue -Dmaven.compile.forktrue 执行…

JDK17 SpringBoot3 整合常见依赖

JDK版本&#xff1a;17 SpringBoot 整合Mybatis Plus 、Redis等 依赖文件 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance&q…

【python】程序运行添加命令行参数argparse模块用法详解

Python标准库之argparse&#xff0c;详解如何创建一个ArgumentParser对象及使用 一. argparse介绍二. 使用步骤及参数介绍三. 具体使用3.1 设置必需参数3.2 传一个参数3.3 传多个参数3.4 位置参数和可选参数3.5 参数设置默认值3.6 其它用法 一. argparse介绍 很多时候&#xff…

Amazon CodeWhisperer 在 vscode 的应用

文章作者:旧花阴 CodeWhisperer 是一款可以帮助程序员更快、更安全地编写代码的工具&#xff0c;可以在他们的开发环境中实时提供代码建议和推荐。亚马逊云科技发布的这款代码生成工具 CodeWhisperer 最大的优势就是对于个人用户免费。以在 vscode 为例&#xff0c;演示安装过程…

LeetCode 1901. 寻找峰值 II:二分查找

【LetMeFly】1901.寻找峰值 II&#xff1a;二分查找 力扣题目链接&#xff1a;https://leetcode.cn/problems/find-a-peak-element-ii/ 一个 2D 网格中的 峰值 是指那些 严格大于 其相邻格子(上、下、左、右)的元素。 给你一个 从 0 开始编号 的 m x n 矩阵 mat &#xff0c…

【漏洞复现】CVE-2023-6895 IP网络对讲广播系统远程命令执行

漏洞描述 杭州海康威视数字技术有限公司IP网络对讲广播系统。 海康威视对讲广播系统3.0.3_20201113_RELEASE(HIK)存在漏洞。它已被宣布为关键。该漏洞影响文件/php/ping.php 的未知代码。使用输入 netstat -ano 操作参数 jsondata[ip] 会导致 os 命令注入。 开发语言:PHP 开…