0

0

Java中的java.nio.ByteBuffer读写模式怎么切换_flip与clear用法

P粉602998670

P粉602998670

发布时间:2026-02-26 13:48:11

|

119人浏览过

|

来源于php中文网

原创

bytebuffer写完后读不到数据是因为未调用flip():写模式下position停在末尾、limit=capacity,flip()将position设为新limit并归零position,使读操作覆盖已写区域。

java中的java.nio.bytebuffer读写模式怎么切换_flip与clear用法

ByteBuffer写完后读不到数据?一定是没调用flip()

写完数据后直接get()get(byte[])返回0或抛BufferUnderflowException,本质是position没重置、limit没收缩。写模式下limit等于capacity,position停在写入末尾;不flip(),读操作就从“末尾”开始读,自然读不到东西。

正确流程只有两步:put()flip()get()。其中flip()干三件事:把当前position设为新的limit(即有效数据长度),把position归零,clear mark(如果有的话)。

  • flip()后position=0,limit=原position,正好覆盖已写区域
  • 多次flip()无害,但反复flip()get()flip()会导致读取范围不断缩小(因为每次get()移动position,下次flip()的limit就变小)
  • 如果写入中途中断(比如只put了3个字节),flip()仍以当前position为准,不会自动补零或截断

想重复写入新数据,该用clear()还是compact()

clear()是重置缓冲区最常用的操作,但它不丢数据——只是把position设为0、limit设为capacity、mark设为-1。底层array()或堆外内存里的字节全还在,只是后续put()会从头覆盖。

真正要保留未读完的数据并追加写,得用compact():它把position到limit之间的未读数据移到buffer开头,然后position设为已复制长度,limit设为capacity。适合“边读边写”的流式场景(比如网络收包后处理一部分,剩下留着和下次数据拼接)。

立即学习Java免费学习笔记(深入)”;

厉害猫AI
厉害猫AI

遥遥领先的AI全职业办公写作平台

下载
  • clear():适合“一次写完→读完→清空→再写”的循环,比如HTTP响应体构造
  • compact():适合“读一部分→处理→剩余数据暂存→等下次数据来拼接”,比如TCP粘包处理
  • rewind()不能代替clear():它只重置position=0,limit不变,无法释放写空间

为什么flip()之后再put()会抛BufferOverflowException

因为flip()后limit被设为之前写入的长度,此时buffer逻辑上是“只读状态”。再调put()就会尝试往[0, limit)区间写,但position从0开始递增,很快超过limit。

典型误操作:写→flip→读一部分→想继续写新数据→直接put。这时必须先clear()(丢弃所有旧数据)或compact()(保留未读部分),才能恢复写能力。

  • 错误链:put(3); flip(); get(1); put(1); → 第二个put()触发异常
  • 修复方式取决于意图:想丢弃全部就clear();想保留未读的2字节就compact()(此时buffer前2字节是原数据,position=2,可继续put)
  • 没有“读写双工”模式:ByteBuffer始终是单向状态机,读写切换必须靠flip()/clear()/compact()

堆内vs堆外ByteBuffer对flip()/clear()有影响吗?

没有。这两个方法只操作buffer的四个元数据字段(mark、position、limit、capacity),和底层内存是否在堆内无关。堆外buffer(ByteBuffer.allocateDirect())执行flip()一样快,也不触发GC。

但要注意:堆外内存的生命周期不由JVM自动管理,即使buffer对象被回收,内存可能滞留。不过这和flip()无关,属于Cleaner机制范畴。

  • 所有ByteBuffer子类(heap/direct/mapped)都继承同一套状态逻辑
  • 唯一影响性能的点是:direct buffer的get()/put()涉及JNI调用,比heap buffer慢,但flip()/clear()本身开销可忽略
  • 别在循环里反复allocateDirect() + clear(),容易触发系统级内存分配失败,应复用buffer
最容易被忽略的是:flip不是“读写切换开关”,而是“写→读”的单向闸门;clear也不是“清空内存”,只是重置指针。状态错乱往往源于把ByteBuffer当成普通byte数组在用,而忘了它本质是个带游标的有限状态机。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

425

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

597

2023.08.10

CSS position定位有几种方式
CSS position定位有几种方式

有4种,分别是静态定位、相对定位、绝对定位和固定定位。更多关于CSS position定位有几种方式的内容,可以访问下面的文章。

83

2023.11.23

http500解决方法
http500解决方法

http500解决方法有检查服务器日志、检查代码错误、检查服务器配置、检查文件和目录权限、检查资源不足、更新软件版本、重启服务器或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

481

2023.11.09

http请求415错误怎么解决
http请求415错误怎么解决

解决方法:1、检查请求头中的Content-Type;2、检查请求体中的数据格式;3、使用适当的编码格式;4、使用适当的请求方法;5、检查服务器端的支持情况。更多http请求415错误怎么解决的相关内容,可以阅读下面的文章。

447

2023.11.14

HTTP 503错误解决方法
HTTP 503错误解决方法

HTTP 503错误表示服务器暂时无法处理请求。想了解更多http错误代码的相关内容,可以阅读本专题下面的文章。

3147

2024.03.12

http与https有哪些区别
http与https有哪些区别

http与https的区别:1、协议安全性;2、连接方式;3、证书管理;4、连接状态;5、端口号;6、资源消耗;7、兼容性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2720

2024.08.16

batoto漫画官网入口与网页版访问指南
batoto漫画官网入口与网页版访问指南

本专题系统整理batoto漫画官方网站最新可用入口,涵盖最新官网地址、网页版登录页面及防走失访问方式说明,帮助用户快速找到batoto漫画官方平台,稳定在线阅读各类漫画内容。

127

2026.02.25

Steam官网正版入口与注册登录指南_新手快速进入游戏平台方法
Steam官网正版入口与注册登录指南_新手快速进入游戏平台方法

本专题系统整理Steam官网最新可用入口,涵盖网页版登录地址、新用户注册流程、账号登录方法及官方游戏商店访问说明,帮助新手玩家快速进入Steam平台,完成注册登录并管理个人游戏库。

17

2026.02.25

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 3.9万人学习

C# 教程
C# 教程

共94课时 | 10.2万人学习

Java 教程
Java 教程

共578课时 | 72.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号