ByteBuffer的介绍
有一个问题需要明确:
为什么要使用bytebuffer,它比byte比起来有什么优点?
很简单:为了提高IO的效率。怎样提高的,这个还得google一下。
记住几个标志的含义:
position[0]:当前指针的位置,也就是接下来要读写的位置。
limit:限制,一个缓冲区可读写的范围。
capability:容量,一个缓冲区最多的存放的字节数。
mark[-1]:标志位,记录当前的位置。
界限是用来控制当前读写的范围,如果容量为100,界限为10,则位置只能在0-10之间,即只能读写0-10之间的数据。
几个操作对它们的影响:(操作都会影响到position,clear和flip会影响到limit)
flip():limit=position, position=0. mark=-1 中文意思是“翻转”。
rewind():position=0,limit不变,可以用于重复读取一段数据. 扩展所有的数据,中文意思是“倒带”,也就是从头开始别的什么也不变。中文意思是“翻转”,也就是当前指,针在哪就在哪,然后从头开始。mark =-1
clear():position=0,limit=capability,也就是相当于清空了之前的内容,但是ByteBuffer中数组的内容在向里面写入之前是没有改变的.所有的位置与使用ByteBuffer.allocate(int capacity)是一样一样的。
mark( ) 就是把当前的Position( ) 设置一个标记!
reset( ) position=mark(); 注意不能为-1 mark位置不变
在 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?
- while (true) {
- buffer.clear(); // 准备将数据写入buffer
- int r = fcin.read( buffer ); // channel读取外部系统的数据并写入 buffer
- if (r==-1) {
- break;
- }
- buffer.flip(); //准备将数据读出buffer
- fcout.write( buffer ); // channel读取buffer的数据并写到相应的外部系统
- }
高级应用
缓存区的分配和包装
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的介绍的更多相关文章
- 一步一图带你深入剖析 JDK NIO ByteBuffer 在不同字节序下的设计与实现
让我们来到微观世界重新认识 Netty 在前面 Netty 源码解析系列 <聊聊 Netty 那些事儿>中,笔者带领大家从宏观世界详细剖析了 Netty 的整个运转流程.从一个网络数据包在 ...
- AIO系列文档(2)----TIO使用
AIO系列文档(1)----图解ByteBuffer中介绍了ByteBuffer用法,下面通过介绍t-io介绍如何使用: hello world例子简介 本例子演示的是一个典型的TCP长连接应用,代码 ...
- spark 源码分析之十七 -- Spark磁盘存储剖析
上篇文章 spark 源码分析之十六 -- Spark内存存储剖析 主要剖析了Spark 的内存存储.本篇文章主要剖析磁盘存储. 总述 磁盘存储相对比较简单,相关的类关系图如下: 我们先从依赖类 Di ...
- spark源码分析以及优化
第一章.spark源码分析之RDD四种依赖关系 一.RDD四种依赖关系 RDD四种依赖关系,分别是 ShuffleDependency.PrunDependency.RangeDependency和O ...
- JAVA NIO 之ByteBuffer的mark、position、limit、flip、reset,get方法介绍
参考博客:http://blog.csdn.net/sunzhenhua0608/article/details/31778519 先来一个demo: import java.nio.ByteBuff ...
- Android中直播视频技术探究之---基础知识大纲介绍
一.前言 最近各种视频直播app到处都是,各种霸屏,当然我们也是需要体验的,关于视频直播的软件这里就不介绍了,在不是技术的人来看,直播是一种潮流,是一种娱乐方式,但是作为一个高技术的,我们除了看看,更 ...
- ByteBuffer解析
一.前言 前一篇文章我们介绍了Android中直播视频技术的基础大纲知识,这里就开始一一讲解各个知识点,首先主要来看一下视频直播中的一个重要的基础核心类:ByteBuffer,这个类看上去都知道了,是 ...
- Cobar介绍及配置
from:http://code.alibabatech.com/wiki/display/cobar/Home Skip to end of metadata Page restrictions ...
- Java 微服务框架 Redkale 入门介绍
Redkale 功能 Redkale虽然只有1.xM大小,但是麻雀虽小五脏俱全.既可作为服务器使用,也可当工具包使用.作为独立的工具包提供以下功能:1.convert包提供JSON的序列化和反序列化功 ...
随机推荐
- java中equals和==区别
equals 方法是 java.lang.Object 类的方法. 有两种用法说明: (1)对于字符串变量来说,使用“==”和“equals()”方法比较字符串时,其比较方法不同. “==”比较两个变 ...
- Java-读取txt生成excel
本段代码的目的是从txt文本中读取相应格式的数据,然后写入到对应格式的excel文档中 在敲本段代码的时候,也学习了一些其它知识点,如下: 1.byte[] b_charset= String.get ...
- 组装需要的json数据格式
在实际项目中有时候会遇到一些有特殊要求的控件,比如easyui-combogrid,加载的并不是常见的json格式,这里我遇到过需要加载类似省市县这种三级数据格式.最后也是从别人的博客中学到的如何组装 ...
- 【Unique Paths II】cpp
题目: Follow up for "Unique Paths": Now consider if some obstacles are added to the grids. H ...
- 牛客网python试题-错误整理-20180711
######## >>>[3] in [1,2,3,4] False >>>3 in [1,2,3,4] True ######## x = (y = z + 1) ...
- SpringCloud Eureka参数配置项详解
SpringCloud Eureka参数配置项详解(转) Eureka涉及到的参数配置项数量众多,它的很多功能都是通过参数配置来实现的,了解这些参数的含义有助于我们更好的应用Eureka的各种功能,下 ...
- js作用域的理解
script:自上而下 全局变量.全局函数 函数:由里到外 浏览器: “JS解析器” 1)“找一些东西”: var function 参数 a = undefine 所有的变量,在正式运行代码之前,都 ...
- P4555 最长双回文串
题目描述 顺序和逆序读起来完全一样的串叫做回文串.比如acbca是回文串,而abc不是(abc的顺序为abc,逆序为cba,不相同). 输入长度为 n的串 S ,求 S的最长双回文子串 T ,即可将 ...
- BZOJ 4175 小G的电话本 ——NTT
后缀自动机统计出现了各种次数的串的和. 就是所谓的生成函数 然后FFT卷积即可. 卷积快速幂$n\log n \log n$ 注意一下实现,可以少两次NTT #include <map> ...
- GROUP BY子句的查询中显示COUNT()为0的结果
含有GROUP BY子句的查询中如何显示COUNT()为0的结果 在SQL Server数据库查询中,为了对查询结果进行对比.分析,我们经常会用到GROUP BY子句以及COUNT()函数来对查询结果 ...