ByteBuffer常用方法与分析

article/2025/11/1 14:33:51

目录

目标

常用API

工具方法

演示案例

allocate(int capacity)和allocateDirect(int capacity)

put()和get()

flip()和hasRemaining()

clear()

compact()

 wrap()

总结


目标

掌握ByteBuffer常用方法,分析ByteBuffer对象在切换读写模式的情况下基本属性的变化情况。

常用API

方法描述案例
allocate(int capacity)分配capacity个字节的缓冲区。返回HeapByteBuffer对象,即jdk内存堆字节缓冲区。ByteBuffer buffer = ByteBuffer.allocate(8);
allocateDirect(int capacity)分配capacity个字节的缓冲区。返回DirectByteBuffer对象,即直接内存字节缓冲区。ByteBuffer buffer = ByteBuffer.allocateDirect(8);
compact()将ByteBuffer切换到写入模式,从position处将缓冲区的字节移动到起始位置。buffer.compact();
get()从ByteBuffer中读取1个字节,并将position向后移动1位。buffer.get();
get(int index)根据index获取指定位置的字节,不会移动position。buffer.get(1);
put(byte[] src)向ByteBuffer写字节数组数据。buffer.put(new byte[]{'1','a'});
buffer.put("1a".getBytes());
put(byte b)向ByteBuffer写字节数据。buffer.put((byte)127);
wrap(byte[] array)向ByteBuffer写字节数组数据。对缓冲区的修改将导致数组被修改,反之亦然。
新缓冲区的大小和limit为字节数组的长度。
ByteBuffer.wrap("Hello World.".getBytes());
flip()将ByteBuffer切换到读模式,position设置为0,limit设置为ByteBuffer内最后1个字节所在的索引数。buffer.flip();
clear()将position设置为0,limit设置为capacity,mark被丢弃。buffer.clear();
capacity()获取ByteBuffer的容量大小。buffer.capacity();
hasRemaining()position和limit之间是否有任何元素。buffer.hasRemaining();

工具方法

    public void bufferDetails(ByteBuffer buffer) {System.out.print("position="+buffer.position());System.out.print(";limit="+buffer.limit());System.out.println(";capacity="+buffer.capacity());//读取数据不移动索引。for (int i = 0; i < buffer.limit(); i++) {System.out.print(buffer.get(i));System.out.print(" ");}System.out.println("\n");}

演示案例

allocate(int capacity)和allocateDirect(int capacity)

    /*** JVM堆内存字节缓冲区* 直接内存字节缓冲区*/public void allocateTest(){ByteBuffer buffer = ByteBuffer.allocate(8);//是否是直接直接内存字节缓冲区System.out.println(buffer.isDirect());ByteBuffer buffer2 = ByteBuffer.allocateDirect(8);//是否是直接直接内存字节缓冲区System.out.println(buffer2.isDirect());}

put()和get()

    /*** 从ByteBuffer中读取1个字节,并将position向后移动1位。*/public void getAndPutTest(){ByteBuffer buffer = ByteBuffer.allocateDirect(20);//注意:这里写入的字节数据size不可以超过ByteBuffer的容量,否则报错。buffer.put("Hello World !".getBytes());//切换到读模式buffer.flip();//position=0System.out.println(buffer.position());//输出72,ASCII表中H就是72System.out.println(buffer.get());//position=1System.out.println(buffer.position());//继续读取字节缓冲区返回position=1位置的数据,即返回e。System.out.println((char)buffer.get());}

flip()和hasRemaining()

    /*** flip():将ByteBuffer切换到读模式,position设置为0,limit设置为ByteBuffer内最后1个字节所在的索引数。* hasRemaining()	position和limit之间是否有任何元素。*/public void flipTest() {ByteBuffer buffer = ByteBuffer.allocateDirect(16);//注意:这里写入的字节数据size不可以超过ByteBuffer的容量,否则报错。buffer.put("123456789".getBytes());bufferDetails(buffer);//切换到读模式buffer.flip();bufferDetails(buffer);//读取数据并移动position。while(buffer.hasRemaining()){System.out.println(buffer.get());}//position=9。bufferDetails(buffer);}

打印结果

clear()

    /*** clear():将position设置为0,limit设置为capacity,mark被丢弃。*/public void clearTest() {ByteBuffer buffer = ByteBuffer.allocateDirect(16);//注意:这里写入的字节数据size不可以超过ByteBuffer的容量,否则报错。buffer.put("123456789".getBytes());//切换到读模式buffer.flip();//读取数据并移动position。while(buffer.hasRemaining()){buffer.get();}//position=9。bufferDetails(buffer);//position=0;limit=16;capacity=16buffer.clear();bufferDetails(buffer);}

打印结果 

compact()

    /*** compact():将ByteBuffer切换到写入模式,从position处将缓冲区的字节移动到起始位置。*/public void compactTest(){ByteBuffer buffer = ByteBuffer.allocateDirect(16);//注意:这里写入的字节数据size不可以超过ByteBuffer的容量,否则报错。buffer.put("123456789".getBytes());//切换到读模式buffer.flip();//读取1个字节。此时的buffer为:position=1;limit=9;capacity=16buffer.get();buffer.compact();bufferDetails(buffer);//切换到读模式buffer.flip();//position=0;limit=8;capacity=16,由此打印证明最后一个9不会被重复读取。bufferDetails(buffer);}

打印结果

 

 wrap()

    /*** 向ByteBuffer写字节数组数据。对缓冲区的修改将导致数组被修改,反之亦然。* 新缓冲区的大小和limit为字节数组的长度。*/public void wrapTest(){byte[] bytes = "123456789".getBytes();ByteBuffer buffer =  ByteBuffer.wrap(bytes);bufferDetails(buffer);buffer.get();buffer.compact();bufferDetails(buffer);//打印234567899,证明了我们对ByteBuffer操作影响了byte[]数组。System.out.println(new String(bytes));bytes[2]='a';//打印了50 51 97 53 54 55 56 57 57,证明了我们对byte[]数组操作影响了ByteBuffer。bufferDetails(buffer);}

打印结果

总结

区分读模式和写模式的标准在于limit属性,如果ByteBuffer存在剩余空间,则:

  • limit=capacity表示当前为写模式
  • limit=数据量表示当前模式为读模式

http://chatgpt.dhexx.cn/article/cy0DyQR7.shtml

相关文章

allocate与allocateDirect的性能测试

allocate与allocateDirect的性能测试 测试工具JMH测试代码JMH结果结论 测试工具JMH java基准测试框架 测试代码 直接分配系统内存(allocateDirect) -测试申请内存性能JVM堆分配内存(allocate)-测试申请内存性能直接内存-操作-连续二十次添加(allocateDirect)-测试内存操作性能…

ByteBuffer.allocate()与ByteBuffer.allocateDirect()方法的区别

在Java中当我们要对数据进行更底层的操作时&#xff0c;一般是操作数据的字节&#xff08;byte&#xff09;形式&#xff0c;这时经常会用到ByteBuffer这样一个类。ByteBuffer提供了两种静态实例方式&#xff1a; public static ByteBuffer allocate(int capacity) public s…

8、ByteBuffer(方法演示2(allocate堆内存和allocateDirect直接内存))

ByteBuffer&#xff08;方法演示2&#xff08;allocate堆内存和allocateDirect直接内存&#xff09;&#xff09; Allocate&#xff1a;java堆内存:读写效率低&#xff0c;收到gc的影响&#xff08;因为我们的java对象也是存在堆内存的&#xff09; &#xff01;&#xff01;…

03 Java NIO allocateDirect()和allocate()区别

03 Java NIO allocateDirect和allocate区别 allocateDirect()和allocate()区别直接与非直接缓冲区直接与非直接缓冲区 源码分析 allocateDirect()和allocate()区别 allocateDirect&#xff1a;分配直接缓冲区&#xff0c;将缓冲区简历在物理内存中&#xff0c;可以提交效率 all…

ByteBuffer.allocate()与ByteBuffer.allocateDirect()方法的区别。

在Java中当我们要对数据进行更底层的操作时&#xff0c;一般是操作数据的字节&#xff08;byte&#xff09;形式&#xff0c;这时经常会用到ByteBuffer这样一个类。ByteBuffer提供了两种静态实例方式&#xff1a; public static ByteBuffer allocate(int capacity) public …

ByteBuffer中的allocate和allocateDirect

1、区别 allocate方法创建的内存在jvm的管理范围&#xff0c;而allocateDirect方法创建的内存不由jvm管理&#xff0c;意思就是allocateDirect创建的内存由系统直接管理 2、释放 allocateDirect创建的内存不归jvm管理&#xff0c;那如何释放呢&#xff1f;虽然这块内存不属于…

NIO ByteBuffer的allocate与allocateDirect区别(HeapByteBuffer与DirectByteBuffer的区别)

参考&#xff1a;https://blog.csdn.net/zhxdick/article/details/81084672 其中allocateDirect分配的字节缓冲区用中文叫做直接缓冲区&#xff08;DirectByteBuffer&#xff09;&#xff0c;用allocate分配的ByteBuffer叫做堆字节缓冲区(HeapByteBuffer).. 其实根据类名就可…

【系统分析师】论文

文章目录 一、论文框架二、相关素材概览2.1 常见开发模型2.2 SOA架构 三、注意事项3.1 岗位职责3.2 项目背景3.3 理论部分讨论3.4 主体内容3.5 结论部分 四、范文4.1 开发模型主题反例正例 4.2 需求获取技术反例正例 4.3 系统测试反例正例 4.4反例正例 一、论文框架 二、相关素…

系统分析员论文12篇合集

系分论文1 企业人事信息系统的应用 【摘要】 本文讨论《企业人事信息系统》项目的需求分析方法与工具的选用。该系统的建设目标是帮助该企业管理好企业内部的人员和人员的活动&#xff0c;人事信息管理指的是企业员工从招聘面试到离职退休的全过程&#xff0c;涉及的主要活动…

系统分析师近几年论文走向

下面是整理的近几年的系统分析师考试论文题目

Java小游戏-俄罗斯方块

摘 要 随着时代的不断发展&#xff0c;个人电脑也在不断普及&#xff0c;一些有趣的桌面游戏已经成为人们在使用计算机进行工作或工作之余休闲娱乐的首选&#xff0c;从最开始的Windows系统自带的黑白棋、纸牌、扫雷等游戏开始&#xff0c;到现在目不暇接的各种游戏&#xff0…

Java版本实现俄罗斯方块小游戏

效果预览图 视频预览&#xff1a; 俄罗斯方块 代码部分 import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.util.Random;public class Block0011 extends JFrame implements KeyListener, ActionListener, MouseListener {// 记分int fenshu…

基于JAVA的俄罗斯方块游戏的设计与实现

目 录 1 引言 1.1 课题研究背景和意义 1.2 国内外现状分析 1.3 课题研究主要内容 1.4 论文组织结构 2 核心技术介绍 2.1 AWT技术介绍 2.2 eclipse编译器介绍 2.3 JAVA集合类技术简介 3 需求分析 3.1 游戏的设计模式 3.2 系统的设计目标 3.3 经济可行…

Java版俄罗斯方块

Java版俄罗斯方块 08年写的一个Java版俄罗斯方块程序 界面做的中规中矩&#xff0c;每种形状颜色都不相同 程序控制还可以&#xff0c;没什么大的Bug 消磨时间的时候可以Down下来玩玩 下载链接&#xff1a;http://download.csdn.net/user/zhaohuihua 菜单选项 也做了不少菜…

Java实现俄罗斯方块

结合网上的资料刚做完课程设计&#xff0c;具体代码如下&#xff1a; public class TetrisPanel extends JPanel{private final int[][] map new int[13][23];// map[列号][行号]。真正的方块区是:21行*10列。边框(2列&#xff0c;1行)// 方块的形状&#xff1a;// 第一维代表…

JAVA编写俄罗斯方块

JAVA编写俄罗斯方块 一.分析游戏界面 首先分析游戏界面&#xff0c;通过游戏界面&#xff0c;抽象出来几种类型。 1.Cell类型 2.Tetromino类型&#xff08;七种组合的父类&#xff09; 3.根据父类定义出七种T,O,I,J,L,S,Z子类型&#xff08;七种组合各自成一个类都继承于父类…

Java简易俄罗斯方块

目前学到Swing第二章&#xff0c;这两天没有学新知识&#xff0c;写了个俄罗斯方块。 写之前想不好怎么实现&#xff0c;找来别人的程序看了一下&#xff0c;再加上自己的想法&#xff0c;做了下面这个半成品&#xff0c;接下来可以加上各种菜单、按钮贴图等美化&#xff0c;都…

使用Java实现小游戏:俄罗斯方块

使用Java实现小游戏&#xff1a;俄罗斯方块 使用一个二维数组保存游戏的地图&#xff1a; // 游戏地图格子&#xff0c;每个格子保存一个方块&#xff0c;数组纪录方块的状态 private State map[][] new State[rows][columns];游戏前先将所有地图中的格子初始化为空&#xf…

JAVA实现经典游戏俄罗斯方块

本文代码来源于B站&#xff1a;尚学堂 博主也在此基础上有些改动&#xff0c;添加了一点提示标签和窗口 本文实现的功能有&#xff1a; 1、 初始化游戏窗口 2、初始化游戏的界面 3、初始化游戏的说明面板 4、随机生成下落方块 5、方块下落速度变化 6、判断方块是否可以下落 7、…