NIO之ByteBuffer

        NIO中的ByteBuffer是缓冲区,其中有几个比较重要的属性capacity,position和limit。

capacity:

        其中,capacity是缓冲区的容量大小,在分配内存空间后不会改变。

limit:

        limit是限制位置,在读写模式切换后limit的位置也跟着切换,切换到读限制位置和写限制位置。在写模式下limit一般位于capacity处,即不超出buffer的范围即可。在读模式下limit一般位于buffer中最后一个字符的位置,即在读的时候不超出存有内容的范围即可。

position:

        position是写入位置或读取位置,在读写切换时也会随之切换。如写模式下随着字符的写入,position的位置会相应地后移,当切换为读模式时,position会一直最前方,此时其代表读取位置。读取操作结束后在切回写模式时,分为两种情况。第一种是使用clear进行切换,之前缓冲区里的全部元素,无论切换前是否读过,都直接抛弃,position移至buffer的最前方。另一种是compact,这种方式是保留没读过的元素,也就是读模式的position和读模式的limit之间的元素,切换写模式时会被保留,position会指向被保留元素的下一个。

如下列的一些图

一开始:

写入4字节:

flip切换为读模式,position切换到读取位置(最前方),limit切换为读取限制,有元素的最后一个位置:

 读了4个字节后:

以clear切换为写模式,元素清空,limit和position也进行切换:

        假设只读了两个字节,剩下的两个没读,并且是以compact方式进行的切换,那会保留没读过的元素,position和limit也切换为写模式,并且position位于保留元素的后方:

       关于position还有需要注意的是, 我们在读模式下进行读取时,一般是调用buffer的get方法,这时每读一个字符指针就会后移一位。注意可以调用 rewind 方法将 position 重新置为 0,或者调用 get(int i) 方法获取索引 i 的内容,它不会移动读指针。另外,使用mark 可以在读取时做一个标记,即使 position 改变,只要调用 reset 就能回到 mark 的位置,但是需注意rewind 和 flip 都会清除 mark 位置。

       实战举例,解决网络收发数据时的半包粘包情况,灵活利用了ByteBuffer读写模式的切换以及对于position的灵活应用:

public static void main(String[] args) {ByteBuffer source = ByteBuffer.allocate(32);//                     11            24source.put("Hello,world\nI'm zhangsan\nHo".getBytes());split(source);source.put("w are you?\nhaha!\n".getBytes());split(source);
}private static void split(ByteBuffer source) {// 切换为读模式source.flip();// buffer中容量的总大小int oldLimit = source.limit();for (int i = 0; i < oldLimit; i++) {// 使用source.get(i)的模式,读取位置position并不会后移if (source.get(i) == '\n') {System.out.println(i);// 当前位置与position间的长度是新字符串长度,position是上一个串的结尾ByteBuffer target = ByteBuffer.allocate(i + 1 - source.position());// 0 ~ limitsource.limit(i + 1);// 从source 读,向 target 写,position后移到该完整串的结尾target.put(source); debugAll(target);source.limit(oldLimit);}}// 有剩余的半包并未真正读取,切换写模式时保留,等后续内容到达补全source.compact();
}

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

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

相关文章

前端crypto-js, 文件加密,判断相同文件、图片(MD5,SHA256)

文章目录 前情提要应用场景实战解析最后前情提要 大家好,今天我们来接触一个库crypto-js 没错,上面是有道翻译的截图,为了我们得到的信息更权威,这个库是用来加密的,但介绍是说,已经停止维护,但并不影响我们在前端项目中的使用,所以学学也没有坏处 应用场景 判断图片…

亿发:新修订器械GSP重大变化,医疗器械GSP软件助力适应科学监管

随着医疗器械行业的快速发展和监管要求的提升&#xff0c;国家药监局近期发布了新修订的医疗器械GSP&#xff08;Good Storage Practice&#xff09;规范&#xff0c;旨在加强医疗器械流通环节的质量管理和监督&#xff0c;确保医疗器械的安全、有效和可追溯。这一重大变化为医…

万益蓝Wonderlab益生菌:吃雪糕的自由,我终于找回来了!

虽然现在不是夏天&#xff0c;但是我必须要来说一下&#xff01;我不仅在夏天可以吃雪糕&#xff01;冬天吃也完全没有问题&#xff01; 夏天&#xff0c;对于很多人来说&#xff0c;是雪糕、冷饮和冰镇西瓜的代名词。但对于我&#xff0c;这简直就是个“禁区”。每次看着别人…

SpringBoot项目启动的时候直接退出了?

SpringBoot项目启动的时候直接退出了&#xff1f; 如下图&#xff1a; 在启动SpringBoot项目的时候仅仅用了1.209s&#xff0c;然后直接退出了&#xff0c;也没有出现启动的项目对应的服务器端口号&#xff1f;为什么会这样呢&#xff1f;因为既然有服务器端口号 那么肯定会有…

【php开发工程师系统性教学】——Laravel框架(验证码)的配置和使用的保姆式教程

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;开发者-曼亿点 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 曼亿点 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a…

MySQL的事务相关的语句的使用

MySQL的事务相关的语句的使用 事务是数据库管理系统执行过程中的一个程序单位&#xff0c;由一个或多个数据库操作组成。MySQL作为一款流行的关系型数据库管理系统&#xff0c;支持事务处理&#xff0c;允许用户定义一系列的操作&#xff0c;这些操作要么完全执行&#xff0c;…

数仓建模—数仓架构发展史

数仓建模—数仓架构发展史 时代的变迁,生死的轮回,历史长河滔滔,没有什么是永恒的,只有变化才是不变的,技术亦是如此,当你选择互联网的那一刻,你就相当于乘坐了一个滚滚向前的时代列车,开往未知的方向,不论什么样的技术架构只有放在当前的时代背景下,才是有意义的,…

MySQl-8.3.0版本安装下载教程(超详细保姆级教程)

第一步&#xff0c;去百度找到MySQl官网 第二步,找到DOWNLOAD&#xff08;下载&#xff09; 第三步 第四步 第五步 第六步.选择倒数第2个 第七步 第八步然后根据步骤安装就好了

MultiCD工具:创建一个多引导Linux USB驱动器

众所周知&#xff0c;拥有一个可安装多个可用操作系统的 CD 或 USB 驱动器在各种情况下都非常有用。无论是为了快速测试或调试某些内容&#xff0c;还是只是重新安装笔记本电脑或 PC 的操作系统&#xff0c;这都可以为你节省大量时间。 在本文中&#xff0c;将介绍如何使用名为…

最新win11配置cuda以及cudnn补丁教程

1、首先使用指令 nvidia-smi 查看电脑支持的**最高cuda**版本&#xff0c;例如&#xff1a;本机 12.2 2、进入CUDA下载cuda安装包 https://developer.nvidia.com/cuda-toolkit-archive 2、点击上方绿色的链接&#xff0c;按照图中序号选择的即可&#xff0c;最后点击下载。 …

VUE识别图片文字OCR(tesseract.js)

效果:1&#xff1a; 效果图2&#xff1a; 一、安装tesseract.js npm i tesseract.js 二、静态页面实现 <template><div><div style"marginTop:100px"><input change"handleChage" type"file" id"image-input"…

计算机网络—— book

文章目录 一、概述1.互联网的核心部分1&#xff0e;电路交换的主要特点2&#xff0e;分组交换的主要特点 2.计算机网络的性能1&#xff0e;速率2&#xff0e;带宽3&#xff0e;吞吐量4&#xff0e;时延5&#xff0e;利用率 3.计算机网络体系结构协议与划分层次具有五层协议的体…

深度学习之视觉特征提取器——VGG系列

VGG 提出论文&#xff1a;1409.1556.pdf (arxiv.org) 引入 距离VGG网络的提出已经约十年&#xff0c;很难想象在深度学习高速发展的今天&#xff0c;一个模型能够历经十年而不衰。虽然如今已经有VGG的大量替代品&#xff0c;但是笔者研究的一些领域仍然有大量工作选择使用VG…

【nodejs】express-generator项目--创建接口及数据库连接

文章目录 一、创建接口1、路由routes&#xff08;1&#xff09;新建路由文件&#xff08;2&#xff09;注册路由 2、控制器controller&#xff08;1&#xff09;新建controller文件&#xff08;2&#xff09;代码 3、services&#xff08;1&#xff09;新建services文件&#x…

Linux - Docker 安装 Nacos

拉取 Nacos 镜像 使用以下命令从 Docker Hub 拉取最新版本的 Nacos 镜像&#xff1a; docker pull nacos/nacos-server启动 Nacos 容器 使用以下命令启动 Nacos 容器&#xff1a; docker run -d \--name nacos \--privileged \--cgroupns host \--env JVM_XMX256m \--env M…

oracle 清空回收站

参考官方文档 select * from user_recyclebin; select * from dba_recyclebin; ---清除回收站中当前用户下的对象 purge recyclebin; ---清除回收站中所有的对象 purge dba_recyclebin; ---清除回收站中指定用户的表 PURGE TABLE owner.table_name; ---清除回收站中指…

Serverless 成本再优化:Knative 支持抢占式实例

作者&#xff1a;元毅、向先 Knative 是一款云原生、跨平台的开源 Serverless 应用编排框架&#xff0c;而抢占式实例是公有云中性价比较高的资源。Knative 与抢占式实例的结合可以进一步降低用户资源使用成本。本文介绍如何在 Knative 中使用抢占式实例。 背景信息 抢占式实…

Python | Leetcode Python题解之第35题搜索插入位置

题目&#xff1a; 题解&#xff1a; class Solution:def searchInsert(self, nums: List[int], target: int) -> int:left, right 0, len(nums) #采用左闭右开区间[left,right)while left < right: # 右开所以不能有,区间不存在mid left (right - left)//2 # 防止溢出…

Java web应用性能分析概叙

“系统慢”&#xff0c;这是任何一个应用都会出现的问题&#xff0c;面对“系统慢”的问题&#xff0c;客户、测试、开发、管理者等不同角色的人员有不同反应&#xff1a; 客户&#xff1a;啥破东西啊&#xff0c;这么卡&#xff01; 测试&#xff1a;性能bug已提交。 开发&…

【OpenGL实验】在python、Qt5、pyOpenGL程序的若干要点

实验效果图: 代码 目录 一、说明二、关于QGLWidget2.1 三个方便的虚函数2.2 析构函数2.3 QGLWidget析构函数三、关于QGLWidget的三个虚函数分工3.1 initializeGL:数据准备、数据绑定分离3.2 resizeGL:视角改变函数3.3 paintGL:绘画函数四、主窗口的配合:刷新周期的设定4…