ByteBuffer的介绍

转摘

有一个问题需要明确:
为什么要使用bytebuffer,它比byte比起来有什么优点?

很简单:为了提高IO的效率。怎样提高的,这个还得google一下。

记住几个标志的含义:
position:当前指针的位置,也就是接下来要读写的位置。
limit:限制,一个缓冲区可读写的范围。
capability:容量,一个缓冲区最多的存放的字节数。
mark:标志位,记录当前的位置。

界限是用来控制当前读写的范围,如果容量为100,界限为10,则位置只能在0-10之间,即只能读写0-10之间的数据。

几个操作对它们的影响:(操作都会影响到position,clear和flip会影响到limit)
flip():limit=position, position=0.中文意思是“翻转”。

rewind():position=0,limit不变,可以用于重复读取一段数据. 扩展所有的数据,中文意思是“倒带”,也就是从头开始别的什么也不变。中文意思是“翻转”,也就是当前指,针在哪就在哪,然后从头开始。

clear():position=0,limit=capability,也就是相当于清空了之前的内容,但是ByteBuffer中数组的内容在向里面写入之前是没有改变的.所有的位置与使用ByteBuffer.allocate(int capacity)是一样一样的。

mark( ) 就是把当前的Position( ) 设置一个标记!

reset( ) position=mark();

转载:Java NIO 学习笔记 - ByteBuffer

在 NIO 库中,所有数据都是用缓冲区处理的。在读取数据时,它是直接读到缓冲区中的。在写入数据时,它是写入到缓冲区中的。任何时候访问 NIO 中的数据,都是将它放到缓冲区中。缓冲区实质上是一个数组。通常它是一个字节数组,但是也可以使用其他种类的数组。但是一个缓冲区不仅仅是一个数组。缓冲区提供了对数据的结构化访问,而且还可以跟踪系统的读/写进程。

buffer其实只是一个美化了的数组。

状态变量

跟踪数据的状态情况使buffer可以自己管理数据资源

position: 其实是指从buffer读取或写入buffer的下一个元素位置。比如,已经写入buffer 3个元素那那么position就是指向第4个位置,即position设置为3(数组从0开始计)。

limit:还有多少数据需要从buffer中取出,或还有多少空间可以放入。postition总是<=limit。

capacity: 表示buffer本身底层数组的容量。limit绝不能>capacity。

filp():作了两件事情:1.将limit指向现在position的位置 2.将position设置为0 (limit=position;position=0)

这个过程可以使之前buffer写入数据时改变的状态变为可以“准备读取”。因为之前写到buffer中的数据就是position 到 limit-1 两个位置之间(limit指向最后一个数据的后一个位置)。

clear():

也作了两件事:1. limit=capacity 2.position=0

这个过程可以使buffer读取数据时改变的状态改变为“清空并准备写入”。

访问方法

以下都以bytebuffer为例

get():

前三个get方法是相对读取。就是相对于位置状态来读取数据,并且会改变position位置状态。

byte get();

ByteBuffer get(byte dst[]);//读取bytebuffer中数据写入 dst[]

ByteBuffer get(byte dst[],int offset, int length);

该读取数据是绝对读取(一个byte),即会忽略limit和position值。并完全绕过了缓冲区的状态统计方法。

就是说不会改变buffer内部的位置状态。

byte get(int index);

put();

与get类似 前四个put方法是相对读取。即受position 以及limit影响,并且会改变 position。

ByteBuffer put( byte b );

ByteBuffer put( byte src[] ); //从src[]写入bytebuffer

ByteBuffer put( byte src[], int offset, int length );

ByteBuffer put( ByteBuffer src );

最后一个是绝对写入 不会影响position等位置状态。

ByteBuffer put( int index, byte b );

除了byte的读写还有其他类型的读写方法。并且他们都存在相对以及绝对两类。

操作的典型使用:

view plaincopy to clipboardprint?

  1. while (true) {
  2. buffer.clear(); // 准备将数据写入buffer
  3. int r = fcin.read( buffer ); // channel读取外部系统的数据并写入 buffer
  4. if (r==-1) {
  5. break;
  6. }
  7. buffer.flip(); //准备将数据读出buffer
  8. fcout.write( buffer ); // channel读取buffer的数据并写到相应的外部系统
  9. }

高级应用

缓存区的分配和包装

ByteBuffer.allocate(int);方法可以分配(创建)一个byte类型的buffer。

ByteBuffer.wrap(byte[]);方法可以将一个已有的byte数组包装出一个新的bytebuffer对象。

后一种方式需要小心处理原来的那个byte数组。因为它可以直接访问了。

缓冲区的分片

分片就是建立“子缓冲区”。子缓冲区共享父缓冲区的一部分底层数组位置。

在某种意义上,子缓冲区就像原来的缓冲区中的一个窗口。

这样当改变子缓冲区的内容时,父缓冲区的相应位置也会被改变。

分片操作是根据当前position以及limit的值来确定的。

buffer.position( 3 );

buffer.limit( 7 );

ByteBuffer slice = buffer.slice();

只读缓冲区

asReadOnlyBuffer()方法可以返回一个与原buffer对象一样的对象,只是新的buffer对象是只读的。

直接缓冲区

sun的定义:给定一个直接字节缓冲区,Java 虚拟机将尽最大努力直接对它执行本机 I/O 操作。也就是说,它会在每一次调用底层操作系统的本机 I/O 操作之前(或之后),尝试避免将缓冲区的内容拷贝到一个中间缓冲区中(或者从一个中间缓冲区中拷贝数据)。

创建directbuffer的方式是用ByteBuffer.allocateDirect( int );方法替代ByteBuffer.allocate(int);

内存影射文件I/O

它读写要比其他IO快很多.

他使文件或文件的一部分由内存影射。但是只有操作该部分位置的数据才是以内存方式读写的,而不是整个文件读入内存。(并且他是一个os的底层机制。由os底层异步完成内存与物理磁盘上的数据同步)

影射文件可以通过FileChannel对象的map方法得到。

比如以下就是将一个文件的前1024个字节影射到内存,并创建一个MappedByteBuffer对象返回出来。MappedByteBuffer是ByteBuffer的一个子类。

MappedByteBuffer mbb = fc.map( FileChannel.MapMode.READ_WRITE, start, size );

ByteBuffer的介绍,布布扣,bubuko.com

时间: 2024-10-24 13:22:59

ByteBuffer的介绍的相关文章

Android O (8.0) 新特性介绍

Android O 功能和 API (文章内容均来Google开发者官网,有需要可自行FQ查看更多资料) Android O 为用户和开发者引入多种新功能.本文重点介绍面向开发者的新功能.请务必查阅 android O 行为变更以了解平台变更可能影响您的应用的领域. 通知 在 Android O 中,我们已重新设计通知,以便为管理通知行为和设置提供更轻松和更统一的方式.这些变更包括:  通知渠道:Android O 引入了通知渠道,其允许您为要显示的每种通知类型创建用户可自定义的渠道.用户界面将

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

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

_00017 Kafka的体系结构介绍以及Kafka入门案例(初级案例+Java API的使用)

博文作者:妳那伊抹微笑 个性签名:世界上最遥远的距离不是天涯,也不是海角,而是我站在妳的面前,妳却感觉不到我的存在 技术方向:Flume+Kafka+Storm+Redis/Hbase+Hadoop+Hive+Mahout+Spark ... 云计算技术 转载声明:可以转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明,谢谢合作! qq交流群:214293307  (期待与你一起学习,共同进步) # Kfaka的体系结构 # 学习前言 Kafka的整个学习过程就是自己看官网的文档,出

NETTY 编码器介绍

1. 背景 1.1. 编解码技术 通常我们也习惯将编码(Encode)称为序列化(serialization),它将对象序列化为字节数组,用于网络传输.数据持久化或者其它用途. 反之,解码(Decode)/反序列化(deserialization)把从网络.磁盘等读取的字节数组还原成原始对象(通常是原始对象的拷贝),以方便后续的业务逻辑操作. 进行远程跨进程服务调用时(例如RPC调用),需要使用特定的编解码技术,对需要进行网络传输的对象做编码或者解码,以便完成远程调用. 相关厂商内容 利用 Am

数据库相关中间件介绍

数据库相关中间件介绍 详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt412 这里主要介绍互联网行业内有关数据库的相关中间件.数据库相关平台主要解决以下三个方面的问题: 为海量前台数据提供高性能.大容量.高可用性的访问 为数据变更的消费提供准实时的保障 高效的异地数据同步 应用层通过分表分库中间件访问数据库,包括读操作(Select)和写操作(update, insert和delete等,DDL, DCL).写操作会在数据

Golomb及指数哥伦布编码原理介绍及实现

本文主要有以下三部分内容: 介绍了Golomb编码,及其两个变种:Golomb-Rice和Exp-Golomb的基本原理 C++实现了一个简单的BitStream库,能够方便在bit流和byte数字之间进行转换 C++实现了Golomb-Rice和Exp-Golomb的编码,并进行了测试. 在文章的最后提供了本文中的源代码下载. Golomb编码的基本原理 Golomb编码是一种无损的数据压缩方法,由数学家Solomon W.Golomb在1960年代发明.Golomb编码只能对非负整数进行编码

dr-helper项目设计介绍(一个包含移动端和Web端的点餐管理系统)

一.源码路径 https://github.com/weiganyi/dr-helper 二.界面 通过浏览器访问Web服务,可以看到界面如下: ADT-Bundle编译工程生成dr-helper.apk,安装后可以看到应用界面如下: 三.背景 Java诞生后主要就是用于Web开发,随着Android的兴起,其在移动领域也应用广泛.我在学习了Java相关的一系列技术后,想找个项目来实际运用一下.因此我考虑可以基于Java相关的技术来构建一个包括移动端和Web端的餐厅管理系统,在这个项目里我会综合

ZooKeeper全面介绍

ZooKeeper简介 ZooKeeper是分布式服务框架,主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务.状态同步服务.集群管理.分布式应用配置项的管理等等. ZooKeeper是Apache的子项目,之前是Hadoop项目的一部分,使用Java实现,最新的版本可以通过官网 http://hadoop.apache.org/zookeeper/来获取. ZooKeeper基本概念 角色 ZooKeeper中的角色主要有以下三类,如下表所示: 系统模型如图所示: 设计目的

dr-helper项目设计介绍(一个包括移动端和Web端的点餐管理系统)

一.源代码路径 https://github.com/weiganyi/dr-helper 二.界面 通过浏览器訪问Web服务,能够看到界面例如以下: ADT-Bundle编译project生成dr-helper.apk.安装后能够看到应用界面例如以下: 三.背景 Java诞生后主要就是用于Web开发,随着Android的兴起,其在移动领域也应用广泛.我在学习了Java相关的一系列技术后,想找个项目来实际运用一下.因此我考虑能够基于Java相关的技术来构建一个包含移动端和Web端的餐厅管理系统,