文档章节

NIO ByteBuffer

欧吧在线
 欧吧在线
发布于 2015/06/19 12:46
字数 1327
阅读 16
收藏 0

在 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的数据并写到相应的外部系统   
}
  
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 );

本文转载自:

共有 人打赏支持
欧吧在线
粉丝 0
博文 32
码字总数 4007
作品 0
沈阳
第一章:Netty介绍

整个Netty的API都是异步的。 Callbacks(回调) 下面代码是一个简单的回调: Fetcher.fetchData()方法需传递一个FetcherCallback类型的参数,当获得数据或发生错误时被回调。 FetcherCallback....

李矮矮
2016/09/23
22
0
IoBuffer和ByteBuffer

最近在做通信和传输的项目,大量的使用NIO和Mina,虽然之前一直对这部分比较关注,但是还没有好好的总结一下这方面的内容。今天想写点儿NIO里最基本的一个类ByteBuffer。至于Mina中的IoBuffe...

Gaischen
2012/10/24
0
14
Java NIO ByteBuffer学习

深入理解Apache Mina (6)---- Java Nio ByteBuffer与Mina ByteBuffer的区别 http://chinaestone.iteye.com/blog/468138 DirectBuffer及内存泄漏 http://blog.csdn.net/zhouhl_cn/article/d......

mj4738
2012/10/15
0
0
我所理解的NIO

在Java的NIO中,有三个比较重要的概念:Buffer、Channel和Selector。 结合上一篇文章提到的送花的例子。Buffer对应花,Channel对应A和B与花之间的联系,Selector就是不断进行轮询的线程。 Ch...

康斯但丁
01/13
0
0
JAVA NIO存在的问题

JAVA 包含最新的版本JDK1.8的NIO存在一些问题,这些问题需要在编写NIO程序时要格外关注: NIO跨平台和兼容性问题 NIO是底层API,它的实现依赖于操作系统针对IO操作的APIs. 所以JAVA能在所有操...

cloud-coder
2016/05/04
782
1

没有更多内容

加载失败,请刷新页面

加载更多

CentOS7防火墙firewalld操作

firewalld Linux上新用的防火墙软件,跟iptables差不多的工具。 firewall-cmd 是 firewalld 的字符界面管理工具,firewalld是CentOS7的一大特性,最大的好处有两个:支持动态更新,不用重启服...

dingdayu
今天
1
0
关于组件化的最初步

一个工程可能会有多个版本,有国际版、国内版、还有针对各种不同的渠道化的打包版本、这个属于我们日常经常见到的打包差异化版本需求。 而对于工程的开发,比如以前的公司,分成了有三大块业...

DannyCoder
今天
2
0
Spring的Resttemplate发送带header的post请求

private HttpHeaders getJsonHeader() { HttpHeaders headers = new HttpHeaders(); MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8"); ......

qiang123
昨天
3
0
Spring Cloud Gateway 之 Only one connection receive subscriber allowed

都说Spring Cloud Gateway好,我也来试试,可是配置了总是报下面这个错误: java.lang.IllegalStateException: Only one connection receive subscriber allowed. 困扰了我几天的问题,原来...

ThinkGem
昨天
27
0
学习设计模式——观察者模式

1. 认识观察者模式 1. 定义:定义对象之间一种一对多的依赖关系,当一个对象状态发生变化时,依赖该对象的其他对象都会得到通知并进行相应的变化。 2. 组织结构: Subject:目标对象类,会被...

江左煤郎
昨天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部