澳门新葡萄京娱乐场 3

澳门新葡萄京娱乐场NIO-java.nio.ByteBuffer中flip、rewind、clear方法的区别

缓冲区(buffer)是从将要写入通道(channel)或适逢其会从通道中读出的一段数据。它是叁个怀有数量,并扮演NIO通道端点的靶子。缓冲区为数量访谈和读写进度提供专门的学问编写制定。

 初藳链接     作者:Jakob Jenkov     译者:airu     校对:丁一

Java
NIO中的Buffer用于和NIO通道实行相互。如你所知,数据是从通道读入缓冲区,从缓冲区写入到大路中的。

缓冲区真相上是一块能够写入数据,然后能够从中读取数据的内存。那块内部存款和储蓄器被打包成NIO
Buffer对象,并提供了一组方法,用来方便的拜见该块内部存款和储蓄器。

凭借Channel的应用我们得以知晓,与NIO channel人机联作时使用Java NIO buffer。
如你所知,数据从channel读入缓冲区,并从缓冲区写入通道。buffer本质上是一块内部存款和储蓄器,您能够在其间写入数据,然后您能够重新读取数据。
该内部存款和储蓄器块被封装在二个NIO
Buffer对象中,该指标提供了一组方法,能够更自在地使用内部存款和储蓄器块。

它是NIO和老版Java
I/O的三个至关心敬性格很顽强在险阻艰难或巨大压力面前不屈要区别。早前数据是一向从流(stream)中读写的,今后数量能够从缓冲区读写。在NIO中,通道是流的相近词。想要精通越来越多关于NIO通道的音讯,
请阅读上一篇教程Java
NIO通道。

Buffer的中坚用法

使用Buffer读写多少貌似遵从以下多少个步骤:

  1. 写入数据到Buffer
  2. 调用flip()方法
  3. 从Buffer中读取数据
  4. 调用clear(卡塔尔方法依旧compact(卡塔尔(قطر‎方法

当向buffer写入数据时,buffer会记录下写了微微多少。一旦要读取数据,须要经过flip(卡塔尔(قطر‎方法将Buffer从写形式切换来读情势。在读格局下,能够读取在此之前写入到buffer的享有数据。

设若读完了全体的数码,就要求清空缓冲区,让它能够另行被写入。有三种方法能清空缓冲区:调用clear(卡塔尔(قطر‎或compact(卡塔尔国方法。clear(卡塔尔方法会清空整个缓冲区。compact(State of Qatar方法只会免去已经读过的数量。任何未读的数量都被移到缓冲区的序幕处,新写入的数目将放手缓冲区未读数据的前边。

上边是一个接受Buffer的事例:

RandomAccessFile aFile = new RandomAccessFile(“data/nio-data.txt”,
“rw”);

FileChannel inChannel = aFile.getChannel();

//create buffer with capacity of 48 bytes

ByteBuffer buf = ByteBuffer.allocate(48);

int bytesRead = inChannel.read(buf); //read into buffer.

while (bytesRead != -1) {

    buf.flip();  //make buffer ready for read   

    while(buf.hasRemaining()){

        System.out.print((char) buf.get()); // read 1 byte at a time

    }

    buf.clear(); //make buffer ready for writing

    bytesRead = inChannel.read(buf);

}

aFile.close();

 

Basic Buffer Usage

接收buffer读取和写入数据日常据守以下七个步骤:

  1. Write data into the Buffer
  2. Call buffer.flip()
  3. Read data out of the Buffer
  4. Call buffer.clear(卡塔尔(قطر‎ or
    buffer.compact(卡塔尔国当您将数据写入缓冲区时,缓冲区会记录您写入的数据量。
    一旦您必要读取数据,您供给选拔flip()方法调用将缓冲区从写入情势切换来读取情势。
    在读取方式下,缓冲区可让您读取写入缓冲区的兼具数据。

就算您读完全部的数据,你需求肃清缓冲区,使其计划好再度写入。
你能够由此二种方法来贯彻:通过调用clear()只怕调用compact()。
clear()方法消逝整个缓冲区。 compact()方法只会去掉已经读取的多少。
任何未读数据将被移位到缓冲区的发端处,並且数据就要未读数据之后被写入缓冲区。

上面是三个总结的Buffer使用示例:

RandomAccessFile aFile = new RandomAccessFile("data/nio-data.txt", "rw");FileChannel inChannel = aFile.getChannel();//create buffer with capacity of 48 bytesByteBuffer buf = ByteBuffer.allocate;int bytesRead = inChannel.read; //从buffer里读while (bytesRead != -1) { buf.flip(); //从buffer弹出数据 while(buf.hasRemaining{ System.out.print buf.get; // 一次获取一个字节 } buf.clear(); //make buffer ready for writing bytesRead = inChannel.read;}aFile.close();

澳门新葡萄京娱乐场 1

澳门新葡萄京娱乐场 ,Buffer的capacity,position和limit

缓冲区精气神儿上是一块能够写入数据,然后能够从当中读取数据的内部存款和储蓄器。那块内存被卷入成NIO
Buffer对象,并提供了一组方法,用来便于的拜望该块内部存款和储蓄器。

为了明白Buffer的办事原理,必要熟知它的六本性格:

  • capacity
  • position
  • limit

position和limit的意思决计于Buffer处在读情势只怕写方式。不管Buffer处在怎么样形式,capacity的意义总是同样的。

那边有一个关于capacity,position和limit在读写方式中的表明,详细的表明在插图前面。

澳门新葡萄京娱乐场 2

 

 

Buffer的六本性子

  • capacity
  • position
  • limitlimit和position的意思决计于缓冲区是高居读取依旧写入情势。
    capacity总是意味着相通的,和缓冲区方式毫无干系。

以下是写入和读取方式下容积capacity,地方position和限量limit的验证。
解释如下图所示。

澳门新葡萄京娱乐场 3image.png

NIO缓冲区特色

  • Java NIO的核心构成模块就是缓冲区。
  • 缓冲区提供贰个一定大小的器皿来读取数据。
  • 各类缓冲区都以可读的,但独有一定缓冲区才是可写的。
  • 缓冲区是通道的端点。
  • 只读缓冲区的内容是不可变的,不过其mark、position和limit都以可变的。
  • 默许意况下,缓冲区都不是线程安全的。

capacity

用作一个内部存款和储蓄器块,Buffer有三个一定的大小值,也叫“capacity”.你只好往里写capacity个byte、long,char等项目。一旦Buffer满了,需求将其清空(通过读数据或许免除数据)才干世袭写多少往里写多少。

Capacity

用作一个内部存款和储蓄器块,三个Buffer有多个稳固的大小Capacity,也可以称作“体积”。
您一定要将容积字节,bytes, longs, chars等写入缓冲区。
一旦缓冲区已满,您需求将其清空(读取数据或淹没数据),然后本事向里面写入越来越多多少。

缓冲区项目

每个原始类型都有叁个相应的缓冲区类型。全数的缓冲区类都贯彻了Buffer接口。最常用的缓冲区类型是ByteBuffer。如下是Java
NIO包中提供的缓冲区类型。

  • ByteBuffer
  • CharBuffer
  • ShortBuffer
  • IntBuffer
  • LongBuffer
  • FloatBuffer
  • DoubleBuffer
  • MappedByteBuffer

position

当您写多少到Buffer中时,position表示目前的职位。初阶的position值为0.当三个byte、long等数据写到Buffer后,
position会向前移动到下三个可插入数据的Buffer单元。position最大可为capacity
– 1.

当读取数据时,也是从有些特定岗位读。当将Buffer从写格局切换来读形式,position会被重新载入参数为0.
当从Buffer的position处读取数据时,position向前移动到下四个可读的岗位。

Position

当您将数据写入缓冲区时,您能够在某些地点施行此操作。
最先的义务是0.当叁个字节,长等被写入缓冲区时,地点被提前线指挥部向缓冲区中的下一个单元以插入数据。
地点能够最大限度地改成体量数Capacity –
1。当您从缓冲区读取数据时,你也得以从给定的职位进行读取。
当您将缓冲区从写入格局flip到读取格局时,地点将重新设置为0.在从缓冲区中读取数据时,您能够从岗位读取数据,地点将升高到下二个读取地方。

缓冲区体积

缓冲区有定位大小,大家必须要存款和储蓄少于“固定大小”的数量,固定大小的值就叫做缓冲区的容积。缓冲区一旦填满则必得清空技术重新写入。体积一旦设置好,在缓存区的生命周期内都不会更改。

limit

在写格局下,Buffer的limit表示您最多能往Buffer里写多少多少。
写形式下,limit等于Buffer的capacity。

当切换Buffer到读格局时,
limit代表您最多能读到多少数量。由此,当切换Buffer到读情势时,limit会被设置成写方式下的position值。换句话说,你能读到事前写入的全数数据(limit被设置成已写多少的多寡,那么些值在写形式下正是position)

Limit

在写格局下,缓冲区的限制是足以写入缓冲区的数据量的范围。
在写入形式下,约束等于缓冲区的体积。当将缓冲区flip为读取方式时,节制意味着你可以从数据中读取多少多少的限量。
因而,当将Buffer转换为读取情势时,将写入形式的写入地点设置为限量。
换句话说,您能够读取与写入数量相同的字节(节制设置为写入的字节数,由地方标志)。

缓冲区界限

在写入情势,缓冲区的无尽就特别容积。在读方式中,界限指向缓冲区最终一个数据位的下一人。当缓冲区被写入时,界限一贯依次增加。缓冲区的界限永世大于等于零且小于等于体积,0
<= 界限 <= 体积。

Buffer的类型

Java NIO 有以下Buffer类型

  • ByteBuffer
  • MappedByteBuffer
  • CharBuffer
  • DoubleBuffer
  • FloatBuffer
  • IntBuffer
  • LongBuffer
  • ShortBuffer

p<>

如你所见,那几个Buffer类型代表了差别的数据类型。换句话说,正是足以经过char,short,int,long,float
或 double类型来操作缓冲区中的字节。

MappedByteBuffer 某些特别,在涉及它的特别章节中再讲。

Buffer 类型

  • ByteBuffer
  • MappedByteBuffer
  • CharBuffer
  • DoubleBuffer
  • FloatBuffer
  • IntBuffer
  • LongBuffer
  • ShortBuffer如您所见,这几个Buffer类型表示分歧的数据类型。
    换句话说,它们让您用char,short,int,long,float或double来拍卖缓冲区中的字节。

缓冲区职责

地点指向缓冲区当前地点。当缓冲区成立时,地方设置为零。读写进度中,地方会依次增加加到下二个目录地点。地点恒久在零和界限之间。

Buffer的分配

要想获得四个Buffer对象首先要开展分配。
每一个Buffer类都有三个allocate方法。上面是三个分红48字节capacity的ByteBuffer的事例。

 

1 ByteBuffer buf = ByteBuffer.allocate(48);

 

那是分配三个可存款和储蓄10二十四个字符的CharBuffer:

 

1 CharBuffer buf = CharBuffer.allocate(1024);

 

分红贰个缓冲区

要博得二个Buffer对象,你必需先分配它。
各类Buffer类都有三个allocate()方法。
以下是多少个突显ByteBuffer分配的现身说法,容积为四十八个字节:

ByteBuffer buf = ByteBuffer.allocate;

那是叁个分红CharBuffer的事例,空间为10贰14个字符

CharBuffer buf = CharBuffer.allocate;

缓冲区标识

标记雷同于给缓冲区设置书签。调用 mark(卡塔尔国 时当前地点就被记录下来了,调用
reset(卡塔尔(قطر‎ 时标志的位置就被恢复生机。

缓冲区flip、clear和rewind

缓冲区flip()

flip(State of Qatar 方法用来为缓冲区做希图,举办 get 操作照旧计划新的写入连串。flip()将界限设置到方今职分,然后将地方置为0。

缓冲区clear()

clear(卡塔尔国 方法用来为缓冲区做希图,进行 put 操作还是寻思新的读类别。clear(State of Qatar将界限设置到体积的职分,并将地方置为0。

缓冲区rewind()

rewind(卡塔尔 方法用来再度读取已经取得过的数量。rewind(State of Qatar将缓冲区地方置0。

向Buffer中写多少

写多少到Buffer有两种方法:

  • 从Channel写到Buffer。
  • 透过Buffer的put(卡塔尔(قطر‎方法写到Buffer里。

从Channel写到Buffer的例子

 

1 int bytesRead = inChannel.read(buf); //read into buffer.

 

通过put方法写Buffer的例子:

 

1 buf.put(127);

 

put方法有成都百货上千本子,允许你以不相同的情势把数据写入到Buffer中。比如,
写到叁个钦命的地点,或许把一个字节数组写入到Buffer。
越多Buffer达成的细节仿照效法JavaDoc。

将数据写入Buffer

您能够通过二种方法将数据写入缓冲区:

  1. 将数据从通路写入缓冲区
  2. 透过缓冲区的put()方法自身将数据写入缓冲区。上边是一个来得通道怎样将数据写入缓冲区的事例:

int bytesRead = inChannel.read; 

那是三个因而put()方法将数据写入Buffer的例子:

buf.put; 

put()方法还会有众多别的版本,允许你以三种不一样形式将数据写入缓冲区。
举个例子,写在特定的岗位,或写入缓冲区的字节数组。
有关更加的多详细消息,请参阅具体缓冲区完结的JavaDoc。

如何读NIO缓冲区

  1. 首先创制缓冲区,分配容积。Buffer有三个 allocate(sizeState of Qatar方法,可以回来一个 Buffer 对象。ByteBuffer byteBuffer =
    ByteBuffer.allocate(512卡塔尔;
  2. 扩充 flip 操作,盘算举行读操作。byteBuffer.flip(卡塔尔国;
  3. 下边能够读入数据。int numberOfBytes = fileChannel.read(byteBuffer卡塔尔(قطر‎;
  4. 接下去能够从缓冲区读取数据。char c = (char卡塔尔国byteBuffer.get(State of Qatar;

flip()方法

flip方法将Buffer从写形式切换成读方式。调用flip(卡塔尔方法会将position设回0,并将limit设置成此前position的值。

换句话说,position现在用于标识读的地点,limit表示从前写进了有一点点个byte、char等
—— 今后能读取多少个byte、char等。

flip()方法

flip()方法将Buffer从写入形式切换成读取格局。
调用flip()会将地方设置回0,并将约束设置在刚刚地点的岗位。换句话说,地方以往标识为读取地点,並且约束标志有稍许个字节,字符等被写入到缓冲区中.

如何写NIO缓冲区

  1. 创办缓冲区,分配容积。ByteBuffer byteBuffer =
    ByteBuffer.allocate(512卡塔尔; //容积设为512
  2. 写入数据。byteBuffer.put((byteState of Qatar 0xff卡塔尔国;

如上便是读写缓冲区的三个例证。缓冲区有很三体系型以至众各种读写方法。你能够依照使用要求开展选择。

从Buffer中读取数据

从Buffer中读取数占领二种艺术:

  1. 从Buffer读取数据到Channel。
  2. 动用get(State of Qatar方法从Buffer中读取数据。

从Buffer读取数据到Channel的例子:

 

1 //read from buffer into channel.

 

 

2 int bytesWritten = inChannel.write(buf);

 

选用get(卡塔尔国方法从Buffer中读取数据的事例

 

1 byte aByte = buf.get();

 

get方法有众多本子,允许你以分裂的艺术从Buffer中读取数据。举例,从钦命position读取,大概从Buffer中读取数据到字节数组。越来越多Buffer完成的细节参照他事他说加以考查JavaDoc。

从缓冲区读取数据

有二种形式能够从缓冲区读取数据:

  1. 从缓冲区读取数据到叁个坦途。
  2. 运用当中二个get()方法本身从缓冲区中读取数据。上面是三个怎么着将数据从缓冲区读入通道的例证:

int bytesWritten = inChannel.write;

这是八个用到get()方法从Buffer读取数据的例证:

byte aByte = buf.get(); 

get()方法还会有比非常多任何版本,允许你以多样办法从Buffer中读取数据。
例如,读取特定的职位,或从缓冲区读取二个字节数组。
有关更加多详细音讯,请参阅具体缓冲区实现的JavaDoc。

rewind()方法

Buffer.rewind(卡塔尔将position设回0,所以您能够重读Buffer中的全部数据。limit保持不改变,仍旧表示能从Buffer中读取多少个成分(byte、char等)。

rewind()方法

Buffer.rewind()将地方设置回0,所以你能够重复读取缓冲区中的全数数据。
该限量保持不改变,因而依然标志能够从缓冲区读取多少个因素。

clear()与compact()方法

只要读完Buffer中的数据,需求让Buffer希图好再一次被写入。能够经过clear(State of Qatar或compact(State of Qatar方法来实现。

即使调用的是clear(卡塔尔方法,position将被设回0,limit棉被服装置成
capacity的值。换句话说,Buffer
被清空了。Buffer中的数据未有肃清,只是这几个标志告诉我们得以从哪儿早先往Buffer里写多少。

若果Buffer中有一对未读的数码,调用clear(卡塔尔(قطر‎方法,数据将“被忘记”,意味着不再有其余标志会告知您怎么样数据被读过,哪些还一贯不。

借使Buffer中仍然有未读的数码,且三番若干遍还索要那些数据,不过那时想要先先写些数据,那么使用compact(卡塔尔(قطر‎方法。

compact(State of Qatar方法将持有未读的数码拷贝到Buffer起首处。然后将position设到最终三个未读成分正前面。limit属性照旧像clear(卡塔尔方法一致,设置成capacity。未来Buffer筹划好写多少了,可是不会覆盖未读的数据。

clear() and compact()方法

在乎那样几项:

  1. 如若实现从缓冲区读取数据,您必得使缓冲区希图好再一次写入。
    你能够由此调用clear()恐怕经过调用compact()来实现。
  2. 一旦你调用clear(),那么地点被设置回0,并且节制到容积。
    换句话说,缓冲区被裁撤。 缓冲区中的数据不会被免除。
    独有号子告诉您能够在Buffer的什么地方写多少。
  3. 而是只要在调用clear()时Buffer中有别的未读取的数目,那么数量将被“忘记”,那表示你不再有任何标志来提示已读取的数额以至未有读取的数额。
  4. 万一缓冲区中还应该有未读数据,并且您想稍后再读取,但是你必要先写一些多少,则申请调离用compact()并不是clear()。
  5. compact()将享有未读数据复制到Buffer的起来有的。
    然后它将地点设置在最后叁个未读成分之后。
    限定属性还是设置为体量,就疑似clear()相仿。
    未来缓冲区本来就有备无患未雨盘算好写入,可是不会覆盖未读取的数据。

mark()与reset()方法

经过调用Buffer.mark(卡塔尔国方法,能够标识Buffer中的三个特定position。之后能够透过调用Buffer.reset(卡塔尔(قطر‎方法恢复生机到这些position。举个例子:

buffer.mark();

//call buffer.get() a couple of times, e.g. during parsing.

buffer.reset();  //set position back to mark.

 

mark() and reset()方法

您能够因而调用Buffer.mark()方法在Buffer中标志给定的职位。
然后,您能够经过调用Buffer.reset()方法将地点重新设置回标识的岗位。
这里是一个例证:

buffer.mark();//call buffer.get() a couple of times, e.g. during parsing.buffer.reset(); //set position back to mark. 

equals()与compareTo()方法

能够利用equals(卡塔尔(قطر‎和compareTo(卡塔尔(قطر‎方法七个Buffer。

equals() and compareTo()

能够行使equals()和compareTo()相比五个缓冲区。

equals()

当满足下列原则时,表示多少个Buffer相等:

  1. 有同一的品类(byte、char、int等)。
  2. Buffer中剩下的byte、char等的个数相等。
  3. Buffer中具备盈余的byte、char等都同一。

如您所见,equals只是相比Buffer的一有个别,不是每三个在它里面的成分都比较。实际上,它只相比Buffer中的剩余成分。

equals()
  1. 它们是相符的类别(byte,char,int等)
  2. 他俩有同等数量的剩余字节,字符等在缓冲区中。
  3. 具备盈余的字节,字符等是非常的。正如您所观望的,等于只相比缓冲区的一部分,并非每个成分。
    事实上,它只是比较缓冲区中的其他成分。

compareTo()方法

compareTo(State of Qatar方法比非常多个Buffer的剩余成分(byte、char等卡塔尔,
如果满意下列原则,则以为一个Buffer“小于”另二个Buffer:

  1. 先是个不对等的因素小于另三个Buffer中对应的成分 。
  2. 装有因素都十三分,但首先个Buffer比另一个先耗尽(第1个Buffer的成分个数比另二个少卡塔尔。

对缓冲区的读写操作首先要通晓缓冲区的下限、上限和当前岗位。上面那个变量的值对Buffer类中的有个别操作有着举足轻重的效应:

  1. limit:全体对Buffer读写操作都会以limit变量的值作为上限。
  2. position:代表对缓冲区举行读写时,当前游标的任务。
  3. capacity:代表缓冲区的最大容积(平日新建叁个缓冲区的时候,limit的值和capacity的值暗许是突出的)。

flip、rewind、clear那七个点子便是用来安装那一个值的。

compareTo()

compareTo()方法相比三个缓冲区的剩余成分,用于比方 排序。
假如现身以下意况,则以为缓冲区比另一个缓冲区“小”:

  1. 率先个要素等于另一个缓冲区中的对应元素,小于另二个缓冲区中的成分。
  2. 有着的成分都以特别的,但首先个缓冲区在第三个缓冲区早前耗尽了成分。

clear方法

public final Buffer clear()

{

    position = 0; //重新载入参数当前读写地点

    limit = capacity; 

    mark = -1;  //撤消标识

    return this;

}

 

clear方法将缓冲区清空,日常是在重复写缓冲区时调用。

flip方法

public final Buffer flip() {

limit = position;

position = 0;

mark = -1;

return this;

}

反转缓冲区。首先将范围设置为这几天职分,然后将地点设置为
0。假若已定义了符号,则废弃该标志。
常与compact方法一齐行使。平时状态下,在备选从缓冲区中读取数据时调用flip方法。

rewind方法

 

1public final Buffer rewind() {

2 position = 0;

3 mark = -1;

4 return this;

5}

 

 

 

如上二种方法均使用final修饰,java.nio.Buffer的富有子类均选择同一种flip、clear和rewind机制。

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注