java nio之Buffer(一)
Buffer是一个包装了基本数据元素数组的对象,它以及它的子类定义了一系列API用于处理数据缓存。
一、属性
Buffer有四个基本属性:
1、capacity 容量,buffer能够容纳的最大元素数目,在Buffer创建时设定并不能更改
2、limit buffer中有效位置数目
3、position 下一个读或者写的位置
4、mark 用于记忆的标志位,配合reset()使用,初始值未设定,调用mark后将当前position设为值
四者关系:0 <= mark <= position <= limit <= capacity
二、API
public abstract class Buffer {
public final int capacity( )
public final int position( )
public final Buffer position (int newPosition)
public final int limit( )
public final Buffer limit (int newLimit)
public final Buffer mark( )
public final Buffer reset( )
public final Buffer clear( )
public final Buffer flip( )
public final Buffer rewind( )
public final int remaining( )
public final boolean hasRemaining( )
public abstract boolean isReadOnly( );
}
支持链式调用,如:buffer.mark().position(5).reset( );
注意isReadOnly()方法决定了buffer是否可写。
三、操作
以ByteBuffer为例,
1、访问,通过get(),get(index),其中get()从当前position位置读取,get(index)从index位置读取,不改变当前position,下面要说到的put也一样。
2、填充,通过put(byte),put(index,byte),按照绝对位置填充也是不改变当前position属性
3、flipping,试想,我们将填充完毕的buffer传递给socket输出,那么socket读取是依据position属性确定,就会从结尾后一位开始读,这样肯定是不正确的,如果要正确的读取我们先要:
buffer.limit(buffer.position( )).position(0);
将limit设为position, 将position设为0,这个操作就叫flipping,API直接提供了这个操作:
buffer.flip( );
特别注意,flip()方法会改变limit属性,将limit属性从capacity设置为当前position。rewind()方法与flip()类似,但是仅将position设为0,而不改变limit,通常用于重新读取已经被flip的buffer。flip()另一个注意点是,两次调用buffer的flip方法,将使得position和limit属性都为0。
4、迭代取元素:
myByteArray [i] = buffer.get( );
}
int count = buffer.remaining( );
for (int i = 0; i < count, i++) {
myByteArray [i] = buffer.get( );
}
ByteBuffer不是线程安全的,前一种方式适合并发访问,后一种方式效率更高。这两种方式都是一个一个取,效率都比批量取低。
5.clear()方法,将buffer重设为空状态,也就是设置limit=capacity,position=0,以便重复利用。
6.compact()方法,用于压缩buffer,这个方法在多次重复调用时是比较低效。
7.mark(),初始是未定义的,这适合如果调用reset将抛出InvalidMarkException。调用makr()后,将当前position设为mark以便reset时返回。注意,rewind( ), clear( ), and flip( )方法都将丢弃已经创建的mark。调用limit(index),positioon(index),如果index的值小于当前mark,mark也将被丢弃。
8.比较,可以通过equals()和compateTo()方法来比较两个buffer,前一个返回boolean,后一个返回0,-1,1。两个buffer equal的条件是:
1)类型相同
2)剩余元素的数目相等
3)剩余元素也一一相等
9、批量移动数据,为了更有效地进行数据传送,批量的数据存取肯定是不能少的,Buffer及其子类都有提供类似的方法,比如CharBuffer:
public CharBuffer get (char [] dst, int offset, int length)
public final CharBuffer put (char[] src)
public CharBuffer put (char [] src, int offset, int length)
public CharBuffer put (CharBuffer src)
public final CharBuffer put (String src)
public CharBuffer put (String src, int start, int end)
四、创建Buffer
Buffer以及其子类都无法直接new,而必须把通过他们提供的工厂方法来创建。通常有两种方式:
1、allocate,例如
CharBuffer charBuffer = CharBuffer.allocate (100);
将在堆上分配一个可以存储100个字符的数组作为backing store。
2、wrap,包装一个已有的数组:
char [] myArray = new char [100];
CharBuffer charbuffer = CharBuffer.wrap (myArray);
注意,这样的方式创建的Buffer,将不会在堆上创建新的数组,而是直接利用myArray做backing store,这意味着任何对myArray或者buffer的修改都将影响到buffer或者myArray。可以通过public final boolean hasArray(
)方法来判断是否拥有一个数组,通过array()方法取得这个数组。
五、复制Buffer
其实这个复制也是“浅拷贝”,通过duplicate()方法将返回一个新创建的buffer,这个新buffer与原来的Buffer共享数据,一样的capacity,但是有自己的position、limit和mark属性。通过asReadOnlyBuffer()方法复制的buffer与duplicate()类似,但是是只读的,不能调用put。比较特别的是slice()方法,故名思议,类似切割一个Buffer出来,与duplicate类似,但是它将从原来Buffer的当前position开始,并且capacity等于原来Buffer的剩余元素数目,也就是(limit-position)。
java nio之Buffer(一)的更多相关文章
- Java NIO 之 Buffer
Java NIO 之 Buffer Java NIO (Non Blocking IO 或者 New IO)是一种非阻塞IO的实现.NIO通过Channel.Buffer.Selector几个组件的协 ...
- Java NIO之Buffer(缓冲区)
Java NIO中的缓存区(Buffer)用于和通道(Channel)进行交互.数据是从通道读入缓冲区,从缓冲区写入到通道中的. 缓冲区本质上是一块可以写入数据,然后可以从中读取数据的内存.这 ...
- JAVA NIO简介-- Buffer、Channel、Charset 、直接缓冲区、分散和聚集、文件锁
IO 是主存和外部设备 ( 硬盘.终端和网络等 ) 拷贝数据的过程. IO 是操作系统的底层功能实现,底层通过 I/O 指令进行完成. Java标准io回顾 在Java1.4之前的I/O系统中,提供 ...
- Java NIO -- 缓冲区(Buffer)的数据存取
缓冲区(Buffer): 一个用于特定基本数据类型的容器.由 java.nio 包定义的,所有缓冲区都是 Buffer 抽象类的子类.Java NIO 中的 Buffer 主要用于与 NIO 通道进行 ...
- Java NIO 之 Buffer(缓冲区)
一 Buffer(缓冲区)介绍 Java NIO Buffers用于和NIO Channel交互. 我们从Channel中读取数据到buffers里,从Buffer把数据写入到Channels. Bu ...
- 【Java nio】buffer
package com.slp.nio; import org.junit.Test; import java.nio.ByteBuffer; /** * Created by sanglp on 2 ...
- java nio之Buffer
一.JAVA NIO 是在和channel交互的时候使用的.Channel将数据读入缓冲区,然后我们又从缓冲区访问数据.写数据时,首先将要发送的数据按顺序填入缓冲区.基本上,缓冲区只是一个列表,它的所 ...
- Java NIO:Buffer、Channel 和 Selector
Buffer 一个 Buffer 本质上是内存中的一块,我们可以将数据写入这块内存,之后从这块内存获取数据. java.nio 定义了以下几个 Buffer 的实现,这个图读者应该也在不少地方见过了吧 ...
- JAVA NIO缓冲区(Buffer)------ByteBuffer常用方法
参考:https://blog.csdn.net/xialong_927/article/details/81044759 缓冲区(Buffer)就是在内存中预留指定大小的存储空间用来对输入/输出(I ...
随机推荐
- sql server 与C#数据类型对应表
- PDF判断打印是A4还是B5
打印材料通畅就是这样两个规格,之前经常受其困扰,B5规格达成A4会显得字很大,当然本身A4就跟大:如果是A4打成B5字很小的: 其实,判断依据就是Adobe reader里面的,当鼠标滑向左下角的时候 ...
- my9.23(输入输出,写操作)
#include <iostream> #include <fstream> using namespace std; void write(int data,int len) ...
- Uva10766 Organising the Organisation
题目链接戳这里 基尔霍夫矩阵裸题.构建基尔霍夫矩阵(度数矩阵-邻接矩阵),求他的任意\(n-1\)阶主子式的绝对值即为答案. 这题开始用java写,结果BigInteger太慢Tle了. 后来用c++ ...
- BZOJ 1668: [Usaco2006 Oct]Cow Pie Treasures 馅饼里的财富
Description 最近,奶牛们热衷于把金币包在面粉里,然后把它们烤成馅饼.第i块馅饼中含有Ni(1<=Ni<=25)块金币,并且,这个数字被醒目地标记在馅饼表面. 奶牛们把所有烤好的 ...
- JAVA实现前几秒几分钟几天前几年源码
package com.date; import java.text.ParseException; import java.text.SimpleDateFormat; import java.ut ...
- hdu 4454 Stealing a Cake
简单的计算几何: 可以把0-2*pi分成几千份,然后找出最小的: 也可以用三分: #include<cstdio> #include<cmath> #include<al ...
- ASP.NET MVC 下 引用阿里巴巴和IconFont字体路径404问题
参考:http://stackoverflow.com/questions/28169365/font-wont-get-found-on-server-for-firefox# http://blo ...
- 使用 Puppet 在 Windows Azure 中配备 Linux 和 Windows 环境
发布于 2013-12-11 作者 Ross Gardler 微软开放技术有限公司 (MS Open Tech) 很高兴地宣布发行新的 Windows Azure Puppet 模块.通过这个模 ...
- .Net 调式案例—实验4 高CPU(High CPU)回顾
原文地址:http://blog.csdn.net/directionofear/article/details/8033506 如果Web应用程序经常遇到的问题按频率排名的话,我觉得 第一名unha ...