讲师中心 微信公众号
AI工具推荐 视频效率加速

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

秋瑶姑娘_2754

秋瑶姑娘_2754

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

|

139人浏览过

|

来源于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免费学习笔记(深入)”;

sc-java-to-ts-interface
sc-java-to-ts-interface

将后端 Java 接口文档转换为前端 TypeScript 类型定义(interface / type)。输入:飞书文档、Spring Boot 接口文档、Swagger/OpenAPI、手写 API 文档等。输出:包含请求参数与响应结果的 .md 文件,含完整 JSDoc 注释。触发关键词:Java 转 TS、接口转换、生成前端类型、接口文档转 TypeScript、DTO/VO/BO 转 interface、后端文档转前端类型、生成接口类型、类型定义生成。

下载
  • 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工具

更多
墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

超级麦吉

一款通过数字员工协作完成调研、数据分析与文档制作的AI办公平台。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

咔片AIPPT

一款在线AI演示文稿制作工具,可根据主题和内容需求辅助生成PPT结构与页面,提高演示材料制作效率。

相关专题

更多
Java I/O 与 NIO 编程体系合集
Java I/O 与 NIO 编程体系合集

全面讲解 Java I/O 编程的演进与核心 API,涵盖传统 I/O 的字节流(InputStream/OutputStream)与字符流(Reader/Writer)体系、装饰器模式在 I/O 中的应用(BufferedReader/InputStreamReader)、文件读写与目录操作、NIO 核心三要素(Buffer 缓冲区/Channel 通道/Selector 选择器)、ByteBuffer 操作与内存映射文件(Mappe

452

2026.04.29

C++ 智能指针与现代内存管理
C++ 智能指针与现代内存管理

深入讲解 C++ 现代内存管理的核心工具——智能指针,涵盖 unique_ptr 独占所有权语义、shared_ptr 引用计数机制与循环引用问题、weak_ptr 弱引用的应用场景、make_unique/make_shared 工厂函数的性能优势、自定义删除器的编写、RAII 资源管理思想的实践,以及从裸指针迁移到智能指针的重构策略,帮助开发者编写安全无泄漏的现代 C++ 代码。

379

2026.04.23

堆和栈的区别
堆和栈的区别

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

6207

2023.07.18

堆和栈区别
堆和栈区别

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

2628

2023.08.10

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

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

352

2023.11.23

http500解决方法
http500解决方法

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

3683

2023.11.09

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

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

934

2023.11.14

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

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

6626

2024.03.12

Vite 项目如何打包和部署
Vite 项目如何打包和部署

Vite项目打包部署专题汇集生产构建、产物预览、输出目录、资源路径、Nginx与GitHub Pages部署及常见白屏和路由404问题的已审核文章,帮助读者完成上线流程。

20

2026.10.28

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
dev.java 官方:Learn Java
dev.java 官方:Learn Java

共0课时 | 0人学习

Java JDBC数据库连接官方教程
Java JDBC数据库连接官方教程

共0课时 | 0人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn