ByteBuffer说明

概述

ByteBuffer是NIO里用得最多的Buffer,它包含两个实现方式:HeapByteBuffer是基于Java堆的实现,而DirectByteBuffer则使用了unsafe的API进行了堆外的实现。这里只说HeapByteBuffer。

使用

ByteBuffer最核心的方法是put(byte)和get()。分别是往ByteBuffer里写一个字节,和读一个字节。

值得注意的是,ByteBuffer的读写模式是分开的,正常的应用场景是:往ByteBuffer里写一些数据,然后flip(),然后再读出来。

这里插两个Channel方面的对象,以便更好的理解Buffer。

ReadableByteChannel是一个从Channel中读取数据,并保存到ByteBuffer的接口,它包含一个方法:

public int read(ByteBuffer dst) throws IOException;

WritableByteChannel则是从ByteBuffer中读取数据,并输出到Channel的接口:

public int write(ByteBuffer src) throws IOException;

那么,一个ByteBuffer的使用过程是这样的:

byteBuffer = ByteBuffer.allocate(N);

//读取数据,写入byteBuffer

readableByteChannel.read(byteBuffer);

//变读为写

byteBuffer.flip();

//读取byteBuffer,写入数据

writableByteChannel.write(byteBuffer);

看到这里,一般都不太明白flip()干了什么事,先从ByteBuffer结构说起:

ByteBuffer内部字段

byte[] buff

buff即内部用于缓存的数组。

position

当前读取的位置。

mark

为某一读过的位置做标记,便于某些时候回退到该位置。

capacity

初始化时候的容量。

limit

读写的上限,limit<=capacity。

put

写模式下,往buffer里写一个字节,并把postion移动一位。写模式下,一般limit与capacity相等。

flip

写完数据,需要开始读的时候,将postion复位到0,并将limit设为当前postion。

get

从buffer里读一个字节,并把postion移动一位。上限是limit,即写入数据的最后位置。

clear

将position置为0,并不清除buffer内容。

欢迎扫描二维码,关注公众号

时间: 2024-08-26 22:20:39

ByteBuffer说明的相关文章

Android中直播视频技术探究之---基础核心类ByteBuffer解析

一.前言 前一篇文章我们介绍了Android中直播视频技术的基础大纲知识,这里就开始一一讲解各个知识点,首先主要来看一下视频直播中的一个重要的基础核心类:ByteBuffer,这个类看上去都知道了,是字节缓冲区处理字节的,这个类的功能非常强大,也在各个场景都有用到,比如网络数据底层处理,特别是结合网络通道信息处理的时候,还有就是后面要说到的OpenGL技术也要用到,当然在视频处理中也是很重要的,因为要处理视频流信息,比如在使用MediaCodec进行底层的视频流编码的时候,处理的就是字节,我们如

Direct ByteBuffer学习

ByteBuffer有两种一种是heap ByteBuffer,该类对象分配在JVM的堆内存里面,直接由Java虚拟机负责垃圾回收,一种是direct ByteBuffer是通过jni在虚拟机外内存中分配的.通过jmap无法查看该快内存的使用情况.只能通过top来看它的内存使用情况. JVM堆内存大小可以通过-Xmx来设置,同样的direct ByteBuffer可以通过-XX:MaxDirectMemorySize来设置,此参数的含义是当Direct ByteBuffer分配的堆外内存到达指定

NIO byteBUffer 讲解 及Mina 源码分析

1.传统的socket: 阻塞式通信模式 tcp连接: 与服务器连接时 .必须等到连接成功后 才返回 . udp连接: 客户端发送数据 ,必须等到发送成功后返回 . 每建立一个 Scoket连接时, 同事创建一个新线程对该 Socket进行单独通信(采用阻塞式通信 ) 这种方式具有很高的响应速度,并且控制起来也很简单,在连接数较少的时候非常有效,但是如果 对每一个连接都产生一个线程的无疑是对系统资源的一种浪费,如果连接数较多将会出现资源不足的情况 2.1NIO 设计背后的基石:反应器模式,用于事

ByteBuffer的介绍

转摘 有一个问题需要明确:为什么要使用bytebuffer,它比byte比起来有什么优点? 很简单:为了提高IO的效率.怎样提高的,这个还得google一下. 记住几个标志的含义:position:当前指针的位置,也就是接下来要读写的位置.limit:限制,一个缓冲区可读写的范围.capability:容量,一个缓冲区最多的存放的字节数.mark:标志位,记录当前的位置. 界限是用来控制当前读写的范围,如果容量为100,界限为10,则位置只能在0-10之间,即只能读写0-10之间的数据. 几个操

今天学到FileChannel 和 ByteBuffer 出现了NonWritableChannelException

查了半小时的异常,最后发现实际类型居然是输入流,而不是输出流 仅此日记警告自己一定不能心急,晚上累了就好好休息吧.... ByteBuffer.flip();必须在进行读取该ByteBuffer之前调用这个方法,告知ByteBuffer准备数据. ByteBuffer.clear();在读取里面的数据之后,如若想要再次往该ByteBuffer里填充数据,则调用此方法告知准备写入.

ByteBuffer常用方法详解

缓冲区(Buffer) 缓冲区(Buffer)就是在内存中预留指定大小的存储空间用来对输入/输出(I/O)的数据作临时存储,这部分预留的内存空间就叫做缓冲区: 使用缓冲区有这么两个好处: 1.减少实际的物理读写次数 2.缓冲区在创建时就被分配内存,这块内存区域一直被重用,可以减少动态分配和回收内存的次数 举个简单的例子,比如A地有1w块砖要搬到B地 由于没有工具(缓冲区),我们一次只能搬一本,那么就要搬1w次(实际读写次数) 如果A,B两地距离很远的话(IO性能消耗),那么性能消耗将会很大 但是

ByteBuffer源码分析

在进行数据传输的时候,往往需要使用到缓冲区,常用的缓冲区就是JDK NIO类库中提供的java.nio.Buffer,实现类如下: 在使用NIO编程时,最常用的是其中的ByteBuffer,本篇分析ByteBuffer内部的源码实现,顺序从父类Buffer入手,了解父类中基础API的实现,再到各个实现子类的实现. Buffer Buffer是存放一种特定的.原始的数据的容器.Buffer是一种特定原始类型元素的线性的有限序列集合,其核心的属性有capacity.limit.Position. c

今天使用JDK1.8中的ByteBuffer 发现其中基本数据必须要是偶数个的

private static void symmertricScramble(CharBuffer cb) { while (cb.hasRemaining()) { cb.mark(); char c1 = cb.get(); char c2 = cb.get(); cb.reset(); cb.put(c2).put(c1); } } public static void main(String[] args) throws Exception { //如果这里是奇数个的数据就会抛出Buff

ByteBuffer: 当由一个byte[]来生成一个固定不变的ByteBuffer时,使用ByteBuffer.wrap(byte[]);

StringBuilder sb = new StringBuilder(1024); //向sb中写入900个左右的随机字符内容 for(int j=1; j< 50;j++) { sb.append(Math.random()); } //System.out.println("sb:" + sb.length()); long startTime = System.currentTimeMillis(); for(int i=0;i<10000;i++) { /* b

收藏:Non-direct与direct ByteBuffer区别

相信大家都知道,但是两者的区别在什么地方呢?在不同的环境下采用哪种类型的ByteBuffer会更有效率呢?先解释一下两者的区别:Non-directByteBuffer内存是分配在堆上的,直接由Java虚拟机负责垃圾收集,你可以把它想象成一个字节数组的包装类,如下伪码所示:HeapByteBuffer extends ByteBuffer {    byte[] content;    int position, limit, capacity;    ......}而DirectByteBuf