【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…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...
CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...
汇编常见指令
汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...
爬虫基础学习day2
# 爬虫设计领域 工商:企查查、天眼查短视频:抖音、快手、西瓜 ---> 飞瓜电商:京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空:抓取所有航空公司价格 ---> 去哪儿自媒体:采集自媒体数据进…...
自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...
CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝
目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为:一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...
【 java 虚拟机知识 第一篇 】
目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...
