庖丁解牛:NIO核心概念与机制详解 02 _ 缓冲区的细节实现
文章目录
- Pre
- Overview
- 状态变量
- 概述
- Position
- Limit
- Capacity
- 演示: 观察变量
- 访问方法
- get() 方法
- put()方法
- 类型化的 get() 和 put() 方法
- 缓冲区的使用:一个内部循环
Pre
庖丁解牛:NIO核心概念与机制详解 01
接下来我们来看下缓冲区内部细节
Overview
接下来将介绍 NIO 中两个重要的缓冲区组件:状态变量和访问方法 (accessor)
状态变量是"内部统计机制"的关键。每一个读/写操作都会改变缓冲区的状态。通过记录和跟踪这些变化,缓冲区就可能够内部地管理自己的资源。
在从通道读取数据时,数据被放入到缓冲区。在有些情况下,可以将这个缓冲区直接写入另一个通道,但是在一般情况下,您还需要
- 查看数据。这是使用 访问方法 get() 来完成的。
- 同样,如果要将原始数据放入缓冲区中,就要使用访问方法 put()。
状态变量
概述
可以用三个值指定缓冲区在任意时刻的状态:
- position
- limit
- capacity
这三个变量一起可以跟踪缓冲区的状态和它所包含的数据。
我们将详细分析每一个变量,还要介绍它们如何适应典型的读/写(输入/输出)进程。在这个例子中,我们假定要将数据从一个输入通道拷贝到一个输出通道。
Position
可以回想一下,缓冲区实际上就是美化了的数组。在从通道读取时,将所读取的数据放到底层的数组中。 position 变量跟踪已经写了多少数据。更准确地说,它指定了下一个字节将放到数组的哪一个元素中。
因此,如果从通道中读三个字节到缓冲区中,那么缓冲区的 position 将会设置为3,指向数组中第四个元素。
同样,在写入通道时,是从缓冲区中获取数据。 position 值跟踪从缓冲区中获取了多少数据。更准确地说,它指定下一个字节来自数组的哪一个元素。因此如果从缓冲区写了5个字节到通道中,那么缓冲区的 position 将被设置为5,指向数组的第六个元素。
Limit
limit 变量表明还有多少数据需要取出(在从缓冲区写入通道时),或者还有多少空间可以放入数据(在从通道读入缓冲区时)。
position 总是小于或者等于 limit。
Capacity
缓冲区的 capacity 表明可以储存在缓冲区中的最大数据容量。实际上,它指定了底层数组的大小 ― 或者至少是指定了准许我们使用的底层数组的容量。
limit 决不能大于 capacity。
演示: 观察变量
我们首先观察一个新创建的缓冲区。 我们假设这个缓冲区的 总容量 为8个字节。
图给你画好了,戳这里
访问方法
到目前为止,我们只是使用缓冲区将数据从一个通道转移到另一个通道。然而,程序经常需要直接处理数据。例如,可能需要将用户数据保存到磁盘。在这种情况下,必须将这些数据直接放入缓冲区,然后用通道将缓冲区写入磁盘。
或者,可能想要从磁盘读取用户数据。在这种情况下,要将数据从通道读到缓冲区中,然后检查缓冲区中的数据。
get() 方法
ByteBuffer 类中有四个 get() 方法:
1)byte get();
2)ByteBuffer get( byte dst[] );
3)ByteBuffer get( byte dst[], int offset, int length );
4)byte get( int index );
- 第一个方法获取单个字节。
- 第二和第三个方法将一组字节读到一个数组中。
- 第四个方法从缓冲区中的特定位置获取字节。
那些返回 ByteBuffer
的方法只是返回调用它们的缓冲区的 this 值。
此外,我们认为前三个 get()
方法是相对的,而最后一个方法是绝对的。 相对 意味着 get()
操作服从 limit
和 position
值 ― 更明确地说,字节是从当前 position
读取的,而 position
在 get
之后会增加。
另一方面,一个 绝对 方法会忽略 limit
和 position
值,也不会影响它们。事实上,它完全绕过了缓冲区的统计方法。
上面列出的方法对应于 ByteBuffer
类。其他类有等价的 get()
方法,这些方法除了不是处理字节外,其它方面是是完全一样的,它们处理的是与该缓冲区类相适应的类型。
put()方法
ByteBuffer 类中有五个 put() 方法:
1)ByteBuffer put( byte b );
2)ByteBuffer put( byte src[] );
3)ByteBuffer put( byte src[], int offset, int length );
4)ByteBuffer put( ByteBuffer src );
5)ByteBuffer put( int index, byte b );
- 第一个方法 写入(
put
) 单个字节。 - 第二和第三个方法写入来自一个数组的一组字节。
- 第四个方法将数据从一个给定的源
ByteBuffer
写入这个ByteBuffer
。 - 第五个方法将字节写入缓冲区中特定的 位置 。那些返回
ByteBuffer
的方法只是返回调用它们的缓冲区的this
值。
与 get()
方法一样,我们将把 put()
方法划分为 相对 或者 绝对 的。前四个方法是相对的,而第五个方法是绝对的。
上面显示的方法对应于 ByteBuffer
类。其他类有等价的 put()
方法,这些方法除了不是处理字节之外,其它方面是完全一样的。它们处理的是与该缓冲区类相适应的类型。
类型化的 get() 和 put() 方法
除了前些小节中描述的 get()
和 put()
方法, ByteBuffer
还有用于读写不同类型的值的其他方法。
如下所示:
getByte()
getChar()
getShort()
getInt()
getLong()
getFloat()
getDouble()
putByte()
putChar()
putShort()
putInt()
putLong()
putFloat()
putDouble()
事实上,这其中的每个方法都有两种类型 ― 一种是相对的,另一种是绝对的。它们对于读取格式化的二进制数据(如图像文件的头部)很有用。
举个栗子
public class TypesInByteBuffer
{static public void main( String args[] ) throws Exception {ByteBuffer buffer = ByteBuffer.allocate( 64 );buffer.putInt( 30 );buffer.putLong( 7000000000000L );buffer.putDouble( Math.PI );buffer.flip();System.out.println( buffer.getInt() );System.out.println( buffer.getLong() );System.out.println( buffer.getDouble() );}
}
缓冲区的使用:一个内部循环
下面的内部循环概括了使用缓冲区将数据从输入通道拷贝到输出通道的过程。
while (true) {buffer.clear();int r = fcin.read( buffer );if (r==-1) {break;}buffer.flip();fcout.write( buffer );
}
read()
和write()
调用得到了极大的简化,因为许多工作细节都由缓冲区完成了。clear()
和flip()
方法用于让缓冲区在读和写之间切换。
相关文章:

庖丁解牛:NIO核心概念与机制详解 02 _ 缓冲区的细节实现
文章目录 PreOverview状态变量概述PositionLimitCapacity演示: 观察变量 访问方法get() 方法put()方法类型化的 get() 和 put() 方法 缓冲区的使用:一个内部循环 Pre 庖丁解牛:NIO核心概念与机制详解 01 接下来我们来看下缓冲区内部细节 Ov…...
Python itertools模块中的combinations() 函数用法
Python itertools模块中的combinations 函数用法 调用方法示例1示例2 调用方法 itertools.combinations(iterable, r)各个参数意义: iterable:输入数据,数据应该是可迭代的。 r:子序列的长度 返回值:从输入的可迭代数…...

在线预览excel,luckysheet在vue项目中的使用
一. 需求 需要在内网项目中在线预览excel文档,并可以下载 二.在项目中下载并引入luckysheet 1.打开项目根目录,npm i luckyexcel 安装 npm i luckyexcel2.在项目的index.html文件中引入依赖 外网项目中的引入(CDN引入)&#…...

【python】OpenCV—Image Pyramid(8)
文章目录 1 图像金字塔2 拉普拉斯金字塔 1 图像金字塔 高斯金字塔 在 OpenCV 中使用函数 cv2.pyrDown(),实现图像高斯金字塔操作中的向下采样,使用函数 cv2.pyrUp() 实现图像金字塔操作中的向上采样 import cv2img cv2.imread(C://Users/Administrat…...

vue3父组件提交校验多个子组件
实现功能:在父组件提交事件中校验多个子组件中的form 父组件: <script setup lang"ts">import {ref, reactive} from vueimport childForm from ./childForm.vueimport childForm2 from ./childForm2.vuelet approvalRef ref()let ap…...
系统移植-uboot
uboot概述: 操作系统运行之前运行的一小段代码,用于将软硬件环境初始化到 一个合适的状态,为操作系统的加载和运行做准备(其本身不是操作系统) Bootloader基本功能 1.初始化软硬件环境 2.引导加载linux内核 3. 给lin…...

使用FFmpeg合并多个ts视频文件转为mp4格式
前言 爬取完视频发现都是ts文件,而且都是几百KB的视频片段,.ts 全名叫:MPEG Transport Stream,它是一个万能的多媒体容器,可以装下音频、视频、字幕。有时我们需要将.ts文件转换为其他更加广泛被支持的格式࿰…...

大模型之十二十-中英双语开源大语言模型选型
从ChatGPT火爆出圈到现在纷纷开源的大语言模型,众多出入门的学习者以及跃跃欲试的公司不得不面临的是开源大语言模型的选型问题。 基于开源商业许可的开源大语言模型可以极大的节省成本和加速业务迭代。 当前(2023年11月17日)开源的大语言模型如下&#…...

.Net6 部署到IIS示例
基于FastEndpoints.Net6 框架部署到IIS 环境下载与安装IIS启用与配置访问网站 环境下载与安装 首先下载环境安装程序,如下图所示,根据系统位数选择x86或者x64进行下载安装,网址:Download .NET 6.0。 IIS启用与配置 启用IIS服务 打开控制面板ÿ…...

轻松搭建短域名短链接服务系统,可选权限认证,并自动生成证书认证把nginx的http访问转换为https加密访问,完整步骤和代码
轻松搭建短域名短链接服务系统,可选权限认证,并自动生成证书认证把nginx的http访问转换为https加密访问,完整步骤和代码。 在互联网信息爆炸的时代,网址复杂而冗长,很难在口头告知他人,也难以分享到社交媒体…...
JS 日期格式化
日期格式化 parseTime: // 日期格式化 export function parseTime(time, pattern) {if (arguments.length 0 || !time) {return null}const format pattern || {y}-{m}-{d} {h}:{i}:{s}let dateif (typeof time object) {date time} else {if ((typeof time st…...

右键菜单和弹出菜单的区别
接触windows开发10年了,一直以为"右键菜单"和"弹出菜单"是不同的。 最近刚刚发现,这两种菜单在定义的时候和消息循环处理程序中并没有什么不同,区别只是在于windows底层显示方式。 如下是右键菜单的显示方式࿱…...

查询数据库DQL
DQL 查询基本语法 -- DQL :基本语法; -- 1查询指定的字段 name entrydate 并返回select name , entrydate from tb_emp;-- 2 查询 所有字段 并返回select id, username, password, name, gender, image, job, entrydate, create_time, update_time from tb_emp;-- 2 查询…...
SpringBoot中文乱码问题解决方案
在Spring Boot中,确实没有像传统Web应用程序中需要使用web.xml配置文件。对于中文乱码问题,你可以采取以下几种方式来解决: 在application.properties文件中添加以下配置: spring.http.encoding.charsetUTF-8 spring.http.encod…...

京东联盟flutter插件使用方法
目录 1.京东联盟官网注册申请步骤略~2.安卓端插件配置:3.IOS端插件配置4.其它配置5.京东OAuth授权 文档地址:https://baiyuliang.blog.csdn.net/article/details/134444104 京东联盟flutter插件地址:https://pub.dev/packages/jdkit 1.京东联…...
python电影数据可视化分析系统的设计与实现【附源码】
电影数据可视化分析系统的设计与实现 (一)开题报告,就是确定设计(论文)选题之后,学生在调查研究的基础上撰写的研究计划,主要说明设计(论文)研究目的和意义、研究的条件以及如何开展研究等问题,也可以说是对设计(论文)的论证和设…...

SQLMAP --TAMPER的编写
跟着师傅的文章进行学习 sqlmap之tamper脚本编写_sqlmap tamper编写-CSDN博客 这里学习一下tamper的编写 这里的tamper 其实就是多个绕过waf的插件 通过编写tamper 我们可以学会 在不同过滤下 执行sql注入 我们首先了解一下 tamper的结构 这里我们首先看一个最简单的例子…...

美国服务器:全面剖析其主要优点与潜在缺点
服务器是网站搭建的灵魂。信息化的今天,我们仍需要它来为网站和应用程序提供稳定的运行环境。而美国作为全球信息技术靠前的国家之一,其服务器市场备受关注。那么,美国服务器究竟有哪些主要优点和潜在缺点呢? 优点 数据中心基础设施&a…...

验证二叉搜索树
二叉搜索树 二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结…...

Ubuntu 18.04无网络连接的n种可能办法
文章目录 网络图标消失,Ubuntu无网络连接VMware上Ubuntu18.04,桥接了多个网卡,其中一个用来上网,均设置为静态ip网络桥接链路没有接对路由不对 树莓派同时使用无线网卡和有线网卡,且一个连接内部局域网,一个…...

【AIGC】RAGAS评估原理及实践
【AIGC】RAGAS评估原理及实践 (1)准备评估数据集(2)开始评估2.1 加载数据集2.2 评估忠实性2.3 评估答案相关性2.4 上下文精度2.5 上下文召回率2.6 计算上下文实体召回率 RAGas(RAG Assessment)RAG 评估的缩写ÿ…...
JavaScript ES6 解构:优雅提取数据的艺术
JavaScript ES6 解构:优雅提取数据的艺术 在 JavaScript 的世界中,ES6(ECMAScript 2015)的推出为开发者带来了许多革命性的特性,其中“解构赋值”(Destructuring Assignment)无疑是最受欢迎的功…...
单元测试与QTestLib框架使用
一.单元测试的意义 在软件开发中,单元测试是指对软件中最小可测试单元(通常是函数、类的方法)进行隔离的、可重复的验证。进行单元测试具有以下重要意义: 1.提升代码质量与可靠性: 早期错误检测: 在开发…...

OpenCV CUDA模块图像处理------双边滤波的GPU版本函数bilateralFilter()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 该函数在 GPU 上执行双边滤波操作,是一种非线性平滑滤波器,能够在 保留边缘的同时去除噪声。 函数原型 void cv::cuda:…...
指针的定义与使用
1.指针的定义和使用 int point1(){//定义指针int a 10;//指针定义语法: 数据类型 * 指针变量名int * p;cout << "sizeof (int(*)) --> " << sizeof(p) << endl;//让指针记录变量a的地址 & 取址符p &a ;cout << &qu…...

CentOS 7如何编译安装升级gcc至7.5版本?
CentOS 7如何编译安装升级gcc版本? 由于配置CentOS-SCLo-scl.repo与CentOS-SCLo-scl-rh.repo后执行yum install -y devtoolset-7安装总是异常,遂决定编译安装gcc7.5 # 备份之前的yum .repo文件至 /tmp/repo_bak 目录 mkdir -p /tmp/repo_bak && cd /etc…...

法律大语言模型(Legal LLM)技术架构
目录 摘要 1 法律AI大模型技术架构 1.1 核心架构分层 1.2 法律知识增强机制 2 关键技术突破与对比 2.1 法律专用组件创新 2.2 性能对比(合同审查场景) 3 开发部署实战指南 3.1 环境搭建流程 3.2 合同审查代码示例 4 行业应用与挑战 4.1 典型场景效能提升 4.2 关…...
Ubuntu 下开机自动执行命令的方法
Ubuntu 下开机自动执行命令的方法(使用 crontab) 在日常使用 Ubuntu 或其他 Linux 系统时,我们常常需要让某些程序或脚本在系统启动后自动运行。例如:启动 Clash 代理、初始化服务、定时同步数据等。 本文将介绍一种简单且常用的…...

Server2003 B-1 Windows操作系统渗透
任务环境说明: 服务器场景:Server2003(开放链接) 服务器场景操作系统:Windows7 1.通过本地PC中渗透测试平台Kali对服务器场景Windows进行系统服务及版本扫描渗透测试,并将该操作显示结果中Telnet服务对应的…...

压测软件-Jmeter
1 下载和安装 1.1 检查运行环境 Jmeter需要运行在java环境(JRE 或 JDK)中 在window的"命令提示窗"查看安装的java版本: java -version 1.2 下载Jmeter 从Apache官网下载Jmeter安装包 1.3 解压和运行 解压后,进入bin文件夹,双击jmeter.bat即可…...