Buffer是一个包装了基本数据元素数组的对象,它以及它的子类定义了一系列API用于处理数据缓存。



一、属性

Buffer有四个基本属性:

1、capacity  容量,buffer能够容纳的最大元素数目,在Buffer创建时设定并不能更改

2、limit buffer中有效位置数目

3、position 下一个读或者写的位置

4、mark  用于记忆的标志位,配合reset()使用,初始值未设定,调用mark后将当前position设为值



四者关系:0 <= mark <= position <= limit <= capacity



二、API

package java.nio;

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、迭代取元素:

for (int i = 0; buffer.hasRemaining( ), i++) {

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)

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(一)的更多相关文章

  1. Java NIO 之 Buffer

    Java NIO 之 Buffer Java NIO (Non Blocking IO 或者 New IO)是一种非阻塞IO的实现.NIO通过Channel.Buffer.Selector几个组件的协 ...

  2. Java NIO之Buffer(缓冲区)

    ​ Java NIO中的缓存区(Buffer)用于和通道(Channel)进行交互.数据是从通道读入缓冲区,从缓冲区写入到通道中的. ​ 缓冲区本质上是一块可以写入数据,然后可以从中读取数据的内存.这 ...

  3. JAVA NIO简介-- Buffer、Channel、Charset 、直接缓冲区、分散和聚集、文件锁

    IO  是主存和外部设备 ( 硬盘.终端和网络等 ) 拷贝数据的过程. IO 是操作系统的底层功能实现,底层通过 I/O 指令进行完成. Java标准io回顾 在Java1.4之前的I/O系统中,提供 ...

  4. Java NIO -- 缓冲区(Buffer)的数据存取

    缓冲区(Buffer): 一个用于特定基本数据类型的容器.由 java.nio 包定义的,所有缓冲区都是 Buffer 抽象类的子类.Java NIO 中的 Buffer 主要用于与 NIO 通道进行 ...

  5. Java NIO 之 Buffer(缓冲区)

    一 Buffer(缓冲区)介绍 Java NIO Buffers用于和NIO Channel交互. 我们从Channel中读取数据到buffers里,从Buffer把数据写入到Channels. Bu ...

  6. 【Java nio】buffer

    package com.slp.nio; import org.junit.Test; import java.nio.ByteBuffer; /** * Created by sanglp on 2 ...

  7. java nio之Buffer

    一.JAVA NIO 是在和channel交互的时候使用的.Channel将数据读入缓冲区,然后我们又从缓冲区访问数据.写数据时,首先将要发送的数据按顺序填入缓冲区.基本上,缓冲区只是一个列表,它的所 ...

  8. Java NIO:Buffer、Channel 和 Selector

    Buffer 一个 Buffer 本质上是内存中的一块,我们可以将数据写入这块内存,之后从这块内存获取数据. java.nio 定义了以下几个 Buffer 的实现,这个图读者应该也在不少地方见过了吧 ...

  9. JAVA NIO缓冲区(Buffer)------ByteBuffer常用方法

    参考:https://blog.csdn.net/xialong_927/article/details/81044759 缓冲区(Buffer)就是在内存中预留指定大小的存储空间用来对输入/输出(I ...

随机推荐

  1. 有反斜杠时候,CakePHP往pgsql插入数据异常

    原始数据:INSERT INTO “public”.”tables” (“table”, “columns”) VALUES (‘table1\’, ‘{“col1″:false,”col2″:tru ...

  2. C语言全局变量的定义与声明

    C语言中全局变量的定义与声明困扰着许多C语言初学者.本文讲述了全局变量定义与声明的用法,而且本为也将阐述这种用法的内在原理.我们先从两个错误例子引入,以下两个例程都在vc6.0平台上测试. 两种错误例 ...

  3. Nth Digit | leetcode

    Find the nth digit of the infinite integer sequence 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ... Note: n i ...

  4. Java设计模式之——单例模式

    引自百度百科: 单例模式是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例类的特殊类. 通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系 ...

  5. Android手机上监听短信的两种方式

    Android手机上监听短信有两种方式: 1. 接受系统的短信广播,操作短信内容. 优点:操作方便,适合简单的短信应用. 缺点:来信会在状态栏显示通知信息. AndroidManifest.xml: ...

  6. hdu 1269

    强连通分量题,用tarjin算法: 这是一道很简单的tarjin算法题,基本上就是套模板: 贴代码: #include<cstdio> #include<vector> #in ...

  7. C语言清空输入缓冲区的N种方法对比

    转自C语言清空输入缓冲区的N种方法对比 C语言中有几个基本输入函数: //获取字符系列 int fgetc(FILE *stream); int getc(FILE *stream); int get ...

  8. Cloud Test 在手,宕机时让您不再措手不及

    1月28日,Github 上午 10:04 分宕机了,导致全球各地的用户不能访问.官方回复可能是网络中断引起的,到 10:28 分已经可以正常访问. 对于互联网公司来说,一旦宕机就会措手不及,如何才能 ...

  9. 李洪强iOS开发Swift篇—10_方法

    李洪强iOS开发Swift篇—10_方法 一.简单说明 跟其他面向对象语言一样,Swift中的方法可以分为2大类: (1)实例方法(Instance Methods) 在OC中,实例方法以减号(-)开 ...

  10. [cocos2d]场景切换以及切换进度显示

    本文主要分两个部分叙述,第一是场景切换,第二是场景切换的进度显示. 一.场景切换 参考learn-iphone-and-ipad-cocos2d-game-development 第五章内容 coco ...