ByteBuffer 的 flip 方法,许多人都知道是写操作后,即将要开始读操作,需要flip一把。但是,compact方法,知道的人似乎比较少,它用在什么场景呢?本文就是回答这个问题的。
import java.nio.ByteBuffer;
public class T {
public static void main(String[] args) {
ByteBuffer buf = ByteBuffer.allocate(8);
buf.put((byte)0x00);
buf.put((byte)0x01);
buf.put((byte)0x02);
buf.put((byte)0x03);
System.out.println("连续写入4个:");
System.out.println("\t"+buf);
buf.flip();
System.out.println("Flip后:");
System.out.println("\t"+buf);
byte b0 = buf.get();
byte b1 = buf.get();
System.out.println("连续读出2个:"+b0+" "+b1);
System.out.println("\t"+buf);
buf.compact();
System.out.println("Compact后:(应用场景:上一次读没完,下一次写就开始了)");
System.out.println("\t"+buf);
buf.put((byte)0x04);
buf.put((byte)0x05);
System.out.println("再写入两个数:");
System.out.println("\t"+buf);
buf.flip();
byte b2 = buf.get();
byte b3 = buf.get();
byte b4 = buf.get();
byte b5 = buf.get();
System.out.println("连续读出4个:"+b2+" "+b3+" "+b4+" "+b5);
System.out.println("\t"+buf);
}
}
输出:
连续写入4个:
java.nio.HeapByteBuffer[pos=4 lim=8 cap=8]
Flip后:
java.nio.HeapByteBuffer[pos=0 lim=4 cap=8]
连续读出2个:0 1
java.nio.HeapByteBuffer[pos=2 lim=4 cap=8]
Compact后:(应用场景:上一次读没完,下一次写就开始了)
java.nio.HeapByteBuffer[pos=2 lim=8 cap=8]
再写入两个数:
java.nio.HeapByteBuffer[pos=4 lim=8 cap=8]
连续读出4个:2 3 4 5
java.nio.HeapByteBuffer[pos=4 lim=4 cap=8]
http://www.jarvana.com/jarvana/view/org/apache/mina/mina-core/2.0.0-M2/mina-core-2.0.0-M2-sources.jar!/org/apache/mina/filter/codec/CumulativeProtocolDecoder.java?format=ok
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.apache.mina.filter.codec;
import org.apache.mina.core.buffer.IoBuffer;Class search for 'org.apache.mina.core.buffer.IoBuffer'
import org.apache.mina.core.service.TransportMetadata;Class search for 'org.apache.mina.core.service.TransportMetadata'
import org.apache.mina.core.session.AttributeKey;Class search for 'org.apache.mina.core.session.AttributeKey'
import org.apache.mina.core.session.IoSession;Class search for 'org.apache.mina.core.session.IoSession'
/**
* A {@link ProtocolDecoder} that cumulates the content of received
* buffers to a <em>cumulative buffer</em> to help users implement decoders.
* <p>
* If the received {@link IoBuffer} is only a part of a message.
* decoders should cumulate received buffers to make a message complete or
* to postpone decoding until more buffers arrive.
* <p>
* Here is an example decoder that decodes CRLF terminated lines into
* <code>Command</code> objects:
* <pre>
* public class CrLfTerminatedCommandLineDecoder
* extends CumulativeProtocolDecoder {
*
* private Command parseCommand(IoBuffer in) {
* // Convert the bytes in the specified buffer to a
* // Command object.
* ...
* }
*
* protected boolean doDecode(
* IoSession session, IoBuffer in, ProtocolDecoderOutput out)
* throws Exception {
*
* // Remember the initial position.
* int start = in.position();
*
* // Now find the first CRLF in the buffer.
* byte previous = 0;
* while (in.hasRemaining()) {
* byte current = in.get();
*
* if (previous == '\r' && current == '\n') {
* // Remember the current position and limit.
* int position = in.position();
* int limit = in.limit();
* try {
* in.position(start);
* in.limit(position);
* // The bytes between in.position() and in.limit()
* // now contain a full CRLF terminated line.
* out.write(parseCommand(in.slice()));
* } finally {
* // Set the position to point right after the
* // detected line and set the limit to the old
* // one.
* in.position(position);
* in.limit(limit);
* }
* // Decoded one line; CumulativeProtocolDecoder will
* // call me again until I return false. So just
* // return true until there are no more lines in the
* // buffer.
* return true;
* }
*
* previous = current;
* }
*
* // Could not find CRLF in the buffer. Reset the initial
* // position to the one we recorded above.
* in.position(start);
*
* return false;
* }
* }
* </pre>
* <p>
* Please note that this decoder simply forward the call to
* {@link #doDecode(IoSession, IoBuffer, ProtocolDecoderOutput)} if the
* underlying transport doesn't have a packet fragmentation. Whether the
* transport has fragmentation or not is determined by querying
* {@link TransportMetadata}.
*
* @author The Apache MINA Project (dev@mina.apache.org)
* @version $Rev: 671827 $, $Date: 2008-06-26 10:49:48 +0200 (jeu, 26 jun 2008) $
*/
public abstract class CumulativeProtocolDecoder extends ProtocolDecoderAdapter {
private final AttributeKey BUFFER = new AttributeKey(getClass(), "buffer");
/**
* Creates a new instance.
*/
protected CumulativeProtocolDecoder() {
}
/**
* Cumulates content of <tt>in</tt> into internal buffer and forwards
* decoding request to {@link #doDecode(IoSession, IoBuffer, ProtocolDecoderOutput)}.
* <tt>doDecode()</tt> is invoked repeatedly until it returns <tt>false</tt>
* and the cumulative buffer is compacted after decoding ends.
*
* @throws IllegalStateException if your <tt>doDecode()</tt> returned
* <tt>true</tt> not consuming the cumulative buffer.
*/
public void decode(IoSession session, IoBuffer in,
ProtocolDecoderOutput out) throws Exception {
if (!session.getTransportMetadata().hasFragmentation()) {
doDecode(session, in, out);
return;
}
boolean usingSessionBuffer = true;
IoBuffer buf = (IoBuffer) session.getAttribute(BUFFER);
// If we have a session buffer, append data to that; otherwise
// use the buffer read from the network directly.
if (buf != null) {
boolean appended = false;
// Make sure that the buffer is auto-expanded.
if (buf.isAutoExpand()) {
try {
buf.put(in);
appended = true;
} catch (IllegalStateException e) {
// A user called derivation method (e.g. slice()),
// which disables auto-expansion of the parent buffer.
} catch (IndexOutOfBoundsException e) {
// A user disabled auto-expansion.
}
}
if (appended) {
buf.flip();
} else {
// Reallocate the buffer if append operation failed due to
// derivation or disabled auto-expansion.
buf.flip();
IoBuffer newBuf = IoBuffer.allocate(
buf.remaining() + in.remaining()).setAutoExpand(true);
newBuf.order(buf.order());
newBuf.put(buf);
newBuf.put(in);
newBuf.flip();
buf = newBuf;
// Update the session attribute.
session.setAttribute(BUFFER, buf);
}
} else {
buf = in;
usingSessionBuffer = false;
}
for (;;) {
int oldPos = buf.position();
boolean decoded = doDecode(session, buf, out);
if (decoded) {
if (buf.position() == oldPos) {
throw new IllegalStateException(
"doDecode() can't return true when buffer is not consumed.");
}
if (!buf.hasRemaining()) {
break;
}
} else {
break;
}
}
// if there is any data left that cannot be decoded, we store
// it in a buffer in the session and next time this decoder is
// invoked the session buffer gets appended to
if (buf.hasRemaining()) {
if (usingSessionBuffer) {
buf.compact();
} else {
storeRemainingInSession(buf, session);
}
} else {
if (usingSessionBuffer) {
removeSessionBuffer(session);
}
}
}
/**
* Implement this method to consume the specified cumulative buffer and
* decode its content into message(s).
*
* @param in the cumulative buffer
* @return <tt>true</tt> if and only if there's more to decode in the buffer
* and you want to have <tt>doDecode</tt> method invoked again.
* Return <tt>false</tt> if remaining data is not enough to decode,
* then this method will be invoked again when more data is cumulated.
* @throws Exception if cannot decode <tt>in</tt>.
*/
protected abstract boolean doDecode(IoSession session, IoBuffer in,
ProtocolDecoderOutput out) throws Exception;
/**
* Releases the cumulative buffer used by the specified <tt>session</tt>.
* Please don't forget to call <tt>super.dispose( session )</tt> when
* you override this method.
*/
@Override
public void dispose(IoSession session) throws Exception {
removeSessionBuffer(session);
}
private void removeSessionBuffer(IoSession session) {
session.removeAttribute(BUFFER);
}
private void storeRemainingInSession(IoBuffer buf, IoSession session) {
final IoBuffer remainingBuf = IoBuffer.allocate(buf.capacity()).setAutoExpand(true);
remainingBuf.order(buf.order());
remainingBuf.put(buf);
session.setAttribute(BUFFER, remainingBuf);
}
}
分享到:
相关推荐
在MINA框架中,CumulativeProtocolDecoder是一个关键的解码器组件,它在处理网络数据流时扮演着重要角色。本文将深入探讨CumulativeProtocolDecoder的使用及其背后的原理。 CumulativeProtocolDecoder的设计目标是...
HPsocket是一个高性能、跨平台的TCP/UDP/串口通信中间件库,它提供了丰富的API接口和灵活的事件驱动模型,使得用户可以方便地开发自己的网络应用程序。本文将重点介绍如何使用HPsocket的`TcpPackServer`类来实现封包...
2025职业教育知识竞赛题库(含答案).pptx
"SOA海鸥算法优化下的KELM核极限学习机分类MATLAB代码详解:传感器故障诊断数据集应用与本地EXCEL数据读取功能",(SOA-KELM)海鸥算法SOA优化KELM核极限学习机分类MATLAB代码 代码注释清楚。 main为运行主程序,可以读取本地EXCEL数据。 很方便,容易上手。 (以传感器故障诊断数据集为例) ,核心关键词:SOA-KELM;海鸥算法优化;核极限学习机分类;MATLAB代码;代码注释清楚;main程序;读取本地EXCEL数据;传感器故障诊断数据集。,SOA-KELM分类算法MATLAB代码:海鸥优化核极限学习机,轻松上手,读取EXCEL数据集进行传感器故障诊断
内容概要:本文由世界经济论坛与Capgemini联合发布,主要阐述了AI代理从简单程序演变为复杂自主系统的进程,强调了它们在现代各行业如医疗保健、教育及金融服务等方面所发挥的作用,并讨论了其潜在收益以及伴随的风险和挑战。文中详细介绍了AI代理的发展历程、核心技术趋势(深度学习、强化学习)、多种类型的AI代理及其系统架构,同时对未来的发展方向——多智能体系统进行了展望,探讨了提高生产力、优化资源配置的新机会。 适合人群:对人工智能感兴趣的各界人士,尤其是关注技术创新对企业和社会长远影响的决策者和技术领导者,如商业领袖、政府官员及其他利益相关方。 使用场景及目标:①帮助政策制定者理解AI代理的功能和应用场景;②为企业管理者提供关于部署和管理AI系统的指导;③为研究者指明未来科研方向并探讨伦理和社会责任等问题;④为技术人员揭示当前最先进技术和最佳实践案例。 其他说明:文中还提到了随着更加先进的AI代理不断涌现,确保安全性和有效监管将是未来发展的重要议题之一。此外,跨行业的共识对于将AI代理顺利整合到各个部门至关重要。文章指出需要建立稳健治理机制来保障AI技术健康发展并服务于公共利益最大化的目标。
2025网络安全理论知识考试题(含答案).pptx
项目已获导师指导并通过的高分毕业设计项目,可作为课程设计和期末大作业,下载即用无需修改,项目完整确保可以运行。 包含:项目源码、数据库脚本、软件工具等,该项目可以作为毕设、课程设计使用,前后端代码都在里面。 该系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值。 项目都经过严格调试,确保可以运行!可以放心下载 技术组成 语言:java 开发环境:idea 数据库:MySql8.0 部署环境:Tomcat(建议用 7.x 或者 8.x 版本),maven 数据库工具:navicat
基于FATFS系统的STM32F407 SD卡升级Bootloader程序:自动检测与升级流程,stm32f407 SD卡升级 bootloader程序 基于sdio fatfs系统的stm32 bootloader程序 功能简介: 本程序使用fatfs系统读取bin文件。 开机后会自动检测sd卡,检测到sd卡后,再读取固定名称的bin文件,之后会对bin文件进行首包校验,判断该升级包的起始地址是否正确,正确的话,就循环读取bin文件并写入到flash中。 完成升级。 详细流程请看流程图 ,stm32f407; SD卡升级; bootloader程序; fatfs系统读取bin文件; 检测SD卡; 首包校验; 循环写入flash。,STM32F407 SD卡升级Bootloader程序:基于SDIO FATFS系统实现自动升级功能
2025网络与信息安全技术题库及答案.doc
C# WinForm通用软件开发框架源码,基于VS2019 .NET与DevExpress 21,WebApi连接SQLServer2014数据库,互联网化数据访问模式,C# 源码 WinForm?通用软件开发框架平台源码 基于:C#Winform+ WebApi +SQLServer2014数据库 基于:VS2019.NET? DevExpress 21.2.6控件 基于:SQLServer2014?数据库 客户端通过Http访问WebApi获得json数据的模式,本系统走互联网,只需要把WebApi发布在公网即可。 说明:此框架源码除系统管理功能外,其它无源码 ,C#源码; WinForm; WebApi; SQLServer2014; VS2019.NET; DevExpress控件; 互联网模式; 系统管理功能; 发布。,C# WinForm开发框架:基于DevExpress与WebApi的通用软件平台源码
项目已获导师指导并通过的高分毕业设计项目,可作为课程设计和期末大作业,下载即用无需修改,项目完整确保可以运行。 包含:项目源码、数据库脚本、软件工具等,该项目可以作为毕设、课程设计使用,前后端代码都在里面。 该系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值。 项目都经过严格调试,确保可以运行!可以放心下载 技术组成 语言:java 开发环境:idea 数据库:MySql8.0 部署环境:Tomcat(建议用 7.x 或者 8.x 版本),maven 数据库工具:navicat
基于SqueezeNet迁移学习算法的滚动轴承故障诊断方法研究——在MATLAB r2021b环境下的应用与拓展至多元信号领域的研究,MATLAB环境下一种基于sqeezenet网络迁移学习的滚动轴承故障诊断方法。 算法运行环境为MATLAB r2021b,该代码展示了如何使用深度学习(迁移学习)方法对滚动轴承进行故障诊断,演示了如何将一维轴承振动信号转为二维尺度图图像并使用预训练网络应用迁移学习对轴承故障进行分类。 迁移学习显著减少了传统轴承诊断方法特征提取和特征选择所花费的时间,并在小型数据集中获得了良好的准确性。 算法可迁移至金融时间序列,地震 微震信号,机械振动信号,声发射信号,电压 电流信号,语音信号,声信号,生理信号(ECG,EEG,EMG)等信号。 ,MATLAB环境; SqueezeNet网络; 迁移学习; 滚动轴承故障诊断; 算法运行环境; 一维轴承振动信号转换; 二维尺度图图像; 特征提取和选择; 信号分析;迁移至其他类型信号 (以分号隔开),基于SqueezeNet迁移学习在MATLAB的滚动轴承故障诊断算法优化
基于弱形式PDE建模的COMSOL不相溶两相流渗流水驱油模拟研究,comsol不相溶两相流渗流模拟,水驱油,基于弱形式PDE建模,模型已验证。 ,核心关键词:comsol; 不相溶两相流; 渗流模拟; 水驱油; 弱形式PDE建模; 模型验证。,"基于弱形式PDE建模的COMSOL两相流渗流模拟:验证水驱油模型"
Tiled for Mac是一款功能强大的开源地图编辑器,适用于macOS系统。它支持正交、等距和六边形地图类型,可创建无限大小的地图,并支持多图层编辑。用户可以通过直观的界面快速添加、修改地图元素,使用像素精度放置对象,并支持图块动画和碰撞编辑。Tiled的TMX格式易于理解,支持多种插件扩展,兼容多种游戏引擎,如RPG和平台游戏。它还提供撤销/重做功能,方便用户调整和优化地图。
太阳能光伏MPPT控制蓄电池三阶段充电模型仿真说明文档(附扰动观测法仿真模型,R2015b版),充电控制器,太阳能光伏MPPT控制蓄电池充电模型。 其中,光伏MPPT控制采用扰动观测法(P&O法),蓄电池充电采用三阶段充电控制。 仿真模型附加一份仿真说明文档,便于理解和修改参数。 版本: R2015b ,充电控制器; 光伏MPPT控制; 扰动观测法(P&O法); 蓄电池充电控制; 三阶段充电控制; 仿真模型; 仿真说明文档; 版本:R2015b,"R2015b版:太阳能光伏MPPT三阶段充电控制仿真模型及说明"
项目已获导师指导并通过的高分毕业设计项目,可作为课程设计和期末大作业,下载即用无需修改,项目完整确保可以运行。 包含:项目源码、数据库脚本、软件工具等,该项目可以作为毕设、课程设计使用,前后端代码都在里面。 该系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值。 项目都经过严格调试,确保可以运行!可以放心下载 技术组成 语言:java 开发环境:idea 数据库:MySql8.0 部署环境:Tomcat(建议用 7.x 或者 8.x 版本),maven 数据库工具:navicat
2025医院收费员考试题题库(含答案).docx
"欧姆龙PLC编程新手宝典:标准程序案例集,包括CP1H脉冲编程与触摸屏实战应用",欧姆龙PLC程序欧姆龙案例欧姆龙标准程序 本产品适用于新手或者在校生 本程序包括有欧姆龙CP1H脉冲程序案例,威纶通触摸屏程序,电子版讲义 程序涉及方面广,适合新手入门学习,掌握了这些以后欧姆龙脉冲程序基本通吃,编程起来无压力 本程序设计到CP1H各个轴的程序编写具体用了ACC PLS2 INI等众多指令, 每个轴的程序都是单独的,包括触摸屏在内,您可以直接调用程序套到直接的程序上,只需要把地址稍微改动即可。 本程序适用于新手、自动化专业在校生学习和提高,另外额外赠送主流的CAD电气原理图纸,包含各种主流的PLC接线原理图,各种成功案例,是每个电气工程师学习和提高最必不可少的资料 ,欧姆龙PLC程序; 欧姆龙案例; 欧姆龙标准程序; 新手学习; 在校生; CP1H脉冲程序案例; 威纶通触摸屏程序; 电子版讲义; 编程指令; 程序设计; PLC接线原理图; 成功案例。,欧姆龙PLC入门宝典:从新手到专业工程师的实用指南
"基于Simulink的锂电池SOC估计模型研究:卡尔曼滤波算法的参数辨识与模型优化",锂电池SOC估计模型 simulink SOC估算卡尔曼滤波估算 SOC电池参数辨识模型10个; 卡尔曼滤波算法锂电池SOC估算估算模型15个; 卡尔曼滤波31个; ,锂电池SOC估计模型; Simulink; SOC估算; 卡尔曼滤波估算; 电池参数辨识模型; 锂电池SOC卡尔曼滤波估算模型; 卡尔曼滤波,基于Simulink的锂电池SOC估计与卡尔曼滤波算法研究
苍鹰算法优化BP神经网络参数:多输入单输出预测建模及效果展示 注:此程序为matlab编写,可直接运行出多种预测结果图与评价指标。效果图为测试数据展示,具体预测效果以个人数据为准。,苍鹰优化算法NGO优化BP神经网络的软值和阈值参数做多输入单输出的拟合预测建模。 程序内注释详细直接替数据就可以使用。 程序语言为matlab。 程序直接运行可以出拟合预测图,迭代优化图,线性拟合预测图,多个预测评价指标。 PS:以下效果图为测试数据的效果图,主要目的是为了显示程序运行可以出的结果图,具体预测效果以个人的具体数据为准。 2.由于每个人的数据都是独一无二的,因此无法做到可以任何人的数据直接替就可以得到自己满意的效果。 ,核心关键词: 苍鹰优化算法; NGO优化; BP神经网络; 软值和阈值参数; 多输入单输出拟合预测建模; 程序内注释; MATLAB程序语言; 拟合预测图; 迭代优化图; 线性拟合预测图; 预测评价指标。,基于苍鹰优化算法的NGO-BP神经网络模型:多输入单输出拟合预测建模与评估