【Netty】 ByteBuf的常用API总结
目录
一、ByteBuf介绍
二、ByteBuf创建
1.池化创建 ByteBufAllocator
2.Unpooled (非池化)创建ByteBuf
3.ByteBufUtil 操作ByteBuf
三、读取ByteBuf数据
1.get方法
2.read方法
3.set方法
4.write方法
5.索引管理
6.索引查找
7.索引查找
8.其他方法
本篇主要介绍ByteBuf的常用操作API,Netty性能的卓越表现离不开ByteBuf的巧妙设计,它提供了一系列的缓冲区读写方法,另外为了方便起见还特定义了ByteBufUtil,提供了比较丰富的操作ByteBuf方法。
一、ByteBuf介绍
为了提高性能,Netty重新设计了字节缓冲区ByteBuf,类似Java Nio的ByteBuffer,但工作方式略有区别,比后者更加灵活、高效。
ByteBuf有几个重要属性:
capacity:容量;
0:缓冲区开始位置;
readIndex:下一个读位置;
writeIndex:下一个写位置;
一个ByteBuf对象即可像byte数组一样工作,又可以像IO字节流一样工作。当前的可读数据区是[readIndex,writeIndex);可写区是[writeIndex,capacity);而[0,readIndex)区间的字节是可废弃数据(Discardable),如下图所示:
+-------------------+------------------+------------------+
| discardable bytes | readable bytes | writable bytes |
| | (CONTENT) | |
+-------------------+------------------+------------------+
| | | |
0 <= readerIndex <= writerIndex <= capacity
基本的操作包括
1.从ByteBuf中读取数据,从readerIndex开始向后读取需要的字节数,readerIndex随之改变;
2.向ByteBuf中写数据,从writeIndex开始向后写数据,同时writeIndex随之改变;
3.删除ByteBuf已读数据,从[0,readerIndex)为已读完的数据,为了节省空间需要释放内存,释放示意图如下:
* BEFORE discardReadBytes()** +-------------------+------------------+------------------+* | discardable bytes | readable bytes | writable bytes |* +-------------------+------------------+------------------+* | | | |* 0 <= readerIndex <= writerIndex <= capacity*** AFTER discardReadBytes()** +------------------+--------------------------------------+* | readable bytes | writable bytes (got more space) |* +------------------+--------------------------------------+* | | |* readerIndex (0) <= writerIndex (decreased) <= capacity
4.清空ByteBuf数据,不需要清空数据,通过移动两个指针readerIndex和writeIndex,指向0即可。
* BEFORE clear()** +-------------------+------------------+------------------+* | discardable bytes | readable bytes | writable bytes |* +-------------------+------------------+------------------+* | | | |* 0 <= readerIndex <= writerIndex <= capacity*** AFTER clear()** +---------------------------------------------------------+* | writable bytes (got more space) |* +---------------------------------------------------------+* | |* 0 = readerIndex = writerIndex <= capacity
二、ByteBuf创建
1.池化创建 ByteBufAllocator
即PooledByteBufAllocator
获取ByteBufAllocator,通过以下两种方式获取
//方法1
Channel channel = ...;
ByteBufAllocator allocator = channel.alloc();
//方法2
ChannelHandlerContext ctx = ...;
ByteBufAllocator allocator2 = ctx.alloc();
ByteBufAllocator中创建byteBuf的方法如下
方法名称 | 方法描述 |
buffer() buffer(int) buffer(int, int) | Return a ByteBuf with heap-based or direct data storage |
heapBuffer() heapBuffer(int) heapBuffer(int, int) | Return a ByteBuf with heap-based storage. |
directBuffer() directBuffer(int) directBuffer(int, int) | Return a ByteBuf with direct storage. |
compositeBuffer() compositeBuffer(int) heapCompositeBuffer() heapCompositeBuffer(int) directCompositeBuffer() directCompositeBuffer(int) | Return a CompositeByteBuf that can be expanded by adding heapbased or direct buffers. |
ioBuffer() | Return a ByteBuf that will be used for I/O operations on a socket. |
2.Unpooled (非池化)创建ByteBuf
即UnPooledByteBufAllocator
当未引用 ByteBufAllocator 时,上面的方法无法访问到 ByteBuf。对于这个用例 Netty 提供一个实用工具类称为 Unpooled,,它提供了静态辅助方法来创建非池化的 ByteBuf 实例,方法如下:
方法名称 | 方法描述 |
buffer() buffer(int) buffer(int, int) | Returns an unpooled ByteBuf with heap-based storage |
directBuffer() directBuffer(int) directBuffer(int, int) | Returns an unpooled ByteBuf with direct storage |
wrappedBuffer() | Returns a ByteBuf, which wraps the given data. |
copiedBuffer() | Returns a ByteBuf, which copies the given data |
3.ByteBufUtil 操作ByteBuf
三、读取ByteBuf数据
get/read get不会改变读索引,read会改变读索引
1.get方法
方法名称 | 方法描述 |
getBoolean(int) | 返回当前索引的 Boolean 值 |
getByte(int) getUnsignedByte(int) | 返回当前索引的(无符号)字节 |
getMedium(int) getUnsignedMedium(int) | 返回当前索引的 (无符号) 24-bit 中间值 |
getInt(int) getUnsignedInt(int) | 返回当前索引的(无符号) 整型 |
getLong(int) getUnsignedLong(int) | 返回当前索引的 (无符号) Long 型 |
getShort(int) getUnsignedShort(int) | 返回当前索引的 (无符号) Short 型 |
getBytes(int, ...) | 字节 |
2.read方法
方法名称 | 方法描述 |
readBoolean() | 返回当前索引的Boolean值,读索引加一 |
readByte() readUnsignedByte() | 返回当前索引的(无符号)字节,读索引加一 |
readMedium() readUnsignedMedium() | 返回当前索引的 (无符号) 24-bit 中间值,读索引加3 |
readInt() readUnsignedInt() | 返回当前索引的(无符号) 整型,读索引加4 |
readLong() readUnsignedLong() | 返回当前索引的 (无符号) Long 型,读索引加8 |
readShort() readUnsignedShort() | 返回当前索引的 (无符号) Short 型,读索引加2 |
readBytes(int,int, ...) | 返回当前位置到length得到一个字节数组,读索引加length |
3.set方法
方法名称 | 方法描述 |
setBoolean(int, boolean) | 在指定的索引位置设置 Boolean 值 |
setByte(int, int) | 在指定的索引位置设置 byte 值 |
setMedium(int, int) | 在指定的索引位置设置 24-bit 中间 值 |
setInt(int, int) | 在指定的索引位置设置 int 值 |
setLong(int, long) | 在指定的索引位置设置 long 值 |
setShort(int, int) | 在指定的索引位置设置 short 值 |
4.write方法
方法名称 | 方法描述 |
writeBoolean(boolean) | 在指定的索引位置设置 Boolean 值,写索引加一 |
writeByte(int) | 在指定的索引位置设置 byte 值,写索引加一 |
writeMedium(int) | 在指定的索引位置设置 24-bit 中间 值,写索引加3 |
writeInt(int) | 在指定的索引位置设置 int 值,写索引加4 |
writeLong(long) | 在指定的索引位置设置 long 值,写索引加8 |
writeShort(int) | 在指定的索引位置设置 short 值,写索引加2 |
writeBytes(int,...) | 在当前索引写入一个Byte数组,写索引加数组长度 |
5.索引管理
方法名称 | 方法描述 |
markReaderIndex(), markWriterIndex() | 标记读(写)索引 |
resetReaderIndex() resetWriterIndex() | 读(写)索引回到mark标记的索引值 |
readerIndex(int) writerIndex(int) | 将读(写)索引设置到指定位置 |
clear() | 可以同时设置 readerIndex 和 writerIndex 为 0。这不会清除内存中的内容 |
6.索引查找
方法名称 | 方法描述 |
for EachByte(ByteBufProcessor.FIND_NUL) | 查找byte,返回byte的索引 |
7.索引查找
方法名称 | 方法描述 |
duplicate() slice(int, int) | 所有这些都返回一个新的 ByteBuf 实例包括它自己的 reader, writer 和标记索引。然而,内部数据存储共享就像在一个 NIO 的 ByteBuffer |
copy() copy(int, int) | 返回的 ByteBuf 有数据的独立副本 |
8.其他方法
方法名称 | 方法描述 |
isReadable() | 返回是否有字节可读 |
isWritable() | 返回是否可以写 |
readableBytes() | 返回可以读的字节长度 |
writablesBytes() | 返回可以写的字节长度 |
capacity() | 返回byteBuf的容量 |
maxCapacity() | 返回byteBuf可以有的最大容量 |
hasArray() | 如果byteBuf可以直接返回一个数组就返回true (heap buf才会为true) |
array() | hasArray返回true,该方法就会返回一个数组 |
参考资料
ByteBuf的常用API总结
Netty详解之九:ByteBuf介绍
相关文章:
【Netty】 ByteBuf的常用API总结
目录 一、ByteBuf介绍 二、ByteBuf创建 1.池化创建 ByteBufAllocator 2.Unpooled (非池化)创建ByteBuf 3.ByteBufUtil 操作ByteBuf 三、读取ByteBuf数据 1.get方法 2.read方法 3.set方法 4.write方法 5.索引管理 6.索引查找 7.索引查找 8.其…...
热门敏捷开发管理工具
敏捷管理研发工具可以协助团队更好地进行敏捷开发和管理。以下是几种流行的敏捷管理研发工具: Leangoo:Leangoo领歌一款永久免费的专业敏捷研发管理工具,它覆盖了敏捷项目研发全流程,包括小型团队敏捷开发,规模化敏捷…...

Java分支结构:一次不经意的选择,改变了我的一生。
👑专栏内容:Java⛪个人主页:子夜的星的主页💕座右铭:前路未远,步履不停 目录 一、顺序结构二、分支结构1、if语句2、switch语句 好久不见!命运之轮常常在不经意间转动,有时一个看似微…...

Unity中Shader需要了解的点与向量
文章目录 前言一、点和向量的区别二、向量加法减法1、向量加法2、向量减法(可以把向量减法转化为向量加法) 三、向量的模四、标量1、向量与标量的乘法 前言 Unity中Shader了解使用的…...
Java初始化大量数据到Neo4j中(一)
背景:我们项目第一次部署图数据库,要求我们把现有的业务数据以及关系上线第一时间初始化到Neo4j中。开发环境数据量已经百万级别。生成环境数据量更多。 我刚开始开发的时候,由于对Neo4j的了解并没有很多,第一想到的是用代码通用组…...

Excel·VBA日期时间转换提取正则表达式函数
标准日期转换 Function 标准日期(ByVal str$) As DateDim pat$, result$arr Array("(\d{4}).*?(\d{1,2}).*?(\d{1,2})", "(\d{4}).*?(\d{1}).*?(\d{1,2})")If Len(str) < 8 Then pat arr(1) Else pat arr(0)With CreateObject("vbscript.r…...

Django中的缓存
Django中的缓存 缓存的定义 定义: 缓存是-类可以更快的读取数据的介质统称,也指其它可以加快数据读取的存储方式。一般用来存储临时数据,常用介质的是读取速度很快的内存 意义:视图渲染有一定成本,数据库的频繁查询过高;所以对于低频变动的页…...
Python 编程基础 | 第二章-基础语法 | 2.4、while 语句
一、while 语句 1、循环语句 Python 编程中 while 语句用于循环执行程序,其基本形式为: while 判断条件(condition):执行语句(statements)……例如: count 0 while (count < 9):print(count)count 1while 语句时还有另外两个…...

Qt Charts简介
文章目录 一.图标类型Charts分类1.折线图和样条曲线图2.面积图和散点图3.条形图4.饼图5.误差棒图6.烛台图7.极坐标图 二.坐标轴Axes类型分类三.图例四.图表的互动五.图表样式主题 一.图标类型Charts分类 图表是通过使用系列类的实例并将其添加到QChart或ChartView实例来创建的…...
MinGW、GCC、GNU和MSVC是什么?有什么区别?
在C和C开发中,常常会遇到MinGW、GCC、GNU和MSVC这些术语。本教程将向您解释它们的含义以及它们之间的区别,帮助您更好地理解这些常见的编译工具和开发环境。 MinGW(Minimalist GNU for Windows): MinGW是一个开源的软件…...
引入easyExcel后,导致springboot项目无法开启tomcat
报错信息: Caused by: java.lang.annotation.IncompleteAnnotationException: org.terracotta.statistics.Statistic missing element type at sun.reflect.annotation.AnnotationInvocationHandler.invoke(AnnotationInvocationHandler.java:81) at com.sun.proxy…...

Doris数据库FE——启动流程源码详细解析
Doris中FE主要负责接收和返回客户端请求、元数据以及集群管理、查询计划生成等工作。代码路径:doris/fe/fe-core/src/main/java/org/apache/doris/DorisFE.java 环境检查 在启动FE的时候,主要做环境检查。检查一些启动时必要的环境变量以及初始化配置…...

服务断路器_Resilience4j线程池隔离实现
线程池隔离配置修改YML文件 resilience4j:thread-pool-bulkhead: instances:backendA:# 最大线程池大小maxThreadPoolSize: 4# 核心线程池大小coreThreadPoolSize: 2# 队列容量queueCapacity: 2编写controller /*** 测试线程池服务隔离* return*/Bulkhead(name "backe…...
原神启动原神启动原神启动原神启动
测试游戏抽卡场景是确保玩家可以正常抽取虚拟物品或角色的重要部分。以下是一些可能的游戏抽卡场景的测试用例示例: 1.正常抽卡流程: 2.测试用户是否能够成功进行一次或多次抽卡操作。 3.确保每次抽卡后,用户收到相应的物品或角色。 4.抽卡…...
Glide - Android的图像加载和缓存库,专注于平滑滚动
官网 GitHub - bumptech/glide: An image loading and caching library for Android focused on smooth scrolling 项目介绍 An image loading and caching library for Android focused on smooth scrolling Glide is a fast and efficient open source media management a…...

如何使用 API 接口获取商品数据,从申请 API 接口、使用 API 接口到实际应用,一一讲解
在当今的数字化时代,应用程序接口(API)已经成为数据获取的重要通道。API 接口使得不同的应用程序能够方便地进行数据交换,从而促进了信息的广泛传播和利用。在众多的数据源中,商品数据是一个非常重要的领域,…...

苹果 CMS 原生 Java 白菜影视 App 源码【带打包教程】
苹果 CMS 原生 Java 白菜影视 App 源码是一款功能强大的影视应用程序,支持画中画、投屏、点播、播放前广告和支持普通解析等多种功能。与萝卜 App 源码相比,该套源码更加稳定,且拥有画中画投屏和自定义广告等功能,提高了安全性。 …...

Flutter开发之Package与Plugin
前言 在flutter中有包和插件两个概念,插件 (plugin) 是 package 的一种,全称是 plugin package,我们简称为 plugin,中文叫插件。包(Package)主要指对flutter相关功能的封装,类似于Android中的插件和iOS中的三方库。而插…...

[极客大挑战 2019]RCE ME 取反绕过正则匹配 绕过disable_function设置
目录 取反 1.蚁剑插件绕过 2.baypass disable_function open_dir/disable_function putenv()/LD_PRELOAD 来绕过限制 利用条件 利用思路 有意思。。。。 <?php error_reporting(0); if(isset($_GET[code])){$code$_GET[code];if(strlen($code)>40){die("Th…...
硬盘接口随机
关于硬盘接口 1 首先,关于[物理接口、协议、通道]2 物理接口:通讯中的电,光口,“物理规格,像是公路、铁路”。通道:通讯协议中的应用层以下所有层?“县道,省道,高速&am…...
React Native 开发环境搭建(全平台详解)
React Native 开发环境搭建(全平台详解) 在开始使用 React Native 开发移动应用之前,正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南,涵盖 macOS 和 Windows 平台的配置步骤,如何在 Android 和 iOS…...
Spring Boot 实现流式响应(兼容 2.7.x)
在实际开发中,我们可能会遇到一些流式数据处理的场景,比如接收来自上游接口的 Server-Sent Events(SSE) 或 流式 JSON 内容,并将其原样中转给前端页面或客户端。这种情况下,传统的 RestTemplate 缓存机制会…...
Oracle查询表空间大小
1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...

大型活动交通拥堵治理的视觉算法应用
大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动(如演唱会、马拉松赛事、高考中考等)期间,城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例,暖城商圈曾因观众集中离场导致周边…...

STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...
docker 部署发现spring.profiles.active 问题
报错: org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...

【LeetCode】算法详解#6 ---除自身以外数组的乘积
1.题目介绍 给定一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O…...
HTML前端开发:JavaScript 获取元素方法详解
作为前端开发者,高效获取 DOM 元素是必备技能。以下是 JS 中核心的获取元素方法,分为两大系列: 一、getElementBy... 系列 传统方法,直接通过 DOM 接口访问,返回动态集合(元素变化会实时更新)。…...