java nio 缓冲区_Java NIO 缓冲区

Java NIO 缓冲区

与NIO通道进行交互时,将使用Java NIO缓冲区。如您所知,数据从通道读取到缓冲区,然后从缓冲区写入通道。

缓冲区本质上是一个内存块,您可以在其中写入数据,然后可以在以后再次读取。该内存块包装在NIO Buffer对象中,该对象提供了一组方法,可以更轻松地使用该内存块。

1 Buffer的基本使用

使用Buffer来读取和写入数据通常遵循以下四个步骤:

将数据写入缓冲区

调用buffer.flip()方法

从缓冲区读取数据

调用buffer.clear()或buffer.compact()方法

当您将数据写入缓冲区时,缓冲区会跟踪您已写入多少数据。一旦需要读取数据,就需要使用flip()方法调用将缓冲区从写入模式切换到读取模式。在读取模式下,缓冲区使您可以读取写入缓冲区的所有数据。

读取所有数据后,需要清除缓冲区,以使其准备好再次写入。您可以通过两种方式执行此操作:通过调用clear()或通过 compact()。该clear()方法清除整个缓冲区。该compact() 方法仅清除您已经读取的数据。任何未读的数据都将移到缓冲区的开头,现在将在未读的数据之后将数据写入缓冲区。

以下一个简单的Buffer用法示例:

/**

* 一点教程网: http://www.yiidian.com

*/

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();

2 Buffer的容量、位置、限制

缓冲区本质上是一个内存块,您可以在其中写入数据,然后可以在以后再次读取。该内存块包装在NIO Buffer对象中,该对象提供了一组方法,可以更轻松地使用该内存块。

Buffer对象具有三个您需要熟悉的属性,以了解其Buffer工作原理。分别是:

容量(capacity)

位置(position)

限制(limit)

位置和限制取决于是否Buffer对象在读或写模式。不管缓冲模式如何,容量始终意味着相同。

下图说明写和读模式下的容量,位置和限制的说明。

3d6685b14e254dc3b45826a1fb6ccc8c.png

写入和读取模式下的缓冲区容量,位置和限制。

2.1 容量

作为存储块,Buffer具有一定的固定大小,也称为其“容量”。您只能将capacity字节,long,char等写入缓冲区。缓冲区装满后,需要先清空(读取数据或清除数据),然后才能向其中写入更多数据。

2.2 位置

将数据写入Buffer时,您需要在特定位置进行。最初,该位置为0。将byte,long等数据写入Buffer该位置后,该位置将前进以指向缓冲区中的下一个要插入数据的单元。位置可以最大程度地变为 capacity - 1。

从a读取数据时,Buffer您也从指定位置读取数据。当您 Buffer从写入模式切换到读取模式时,该位置将重置为0。从中读取数据时,Buffer您将从中读取数据position,并position 前进到下一个读取位置。

2.3 限制

在写模式下,Buffer的限制是可以写入缓冲区的数据量的限制。在写入模式下,限制等于的容量Buffer。

当翻转Buffer到读模式,限制意味着多少数据可以从数据中读取的限制。因此,当将a切换Buffer到读取模式时,将限制设置为写入模式的写入位置。换句话说,您可以读取与写入的字节一样多的字节(限制设置为写入的字节数,该字节数由位置标记)。

3 Buffer的类型

Java NIO带有以下缓冲区类型:

ByteBuffer

MappedByteBuffer

CharBuffer

DoubleBuffer

FloatBuffer

IntBuffer

LongBuffer

ShortBuffer

如您所见,这些Buffer类型代表不同的数据类型。换句话说,它们使您可以将缓冲区中的字节作为char,short,int,long,float或double来使用。

4 Buffer的分配

要获取Buffer对象,您必须首先分配它。每个Buffer类都有一个allocate()执行此操作的方法。以下示例显示ByteBuffer了容量为48个字节的a的分配 :

ByteBuffer buf = ByteBuffer.allocate(48);

这是一个CharBuffer为1024个字符分配带空格的示例:

CharBuffer buf = CharBuffer.allocate(1024);

5 将数据写入Buffer

您可以通过Buffer两种方式将数据写入:

将数据从Channel写入Buffer

Buffer通过缓冲区的put()方法将数据写入。

以下代码是Channel如何将数据写入Buffer的示例:

int bytesRead = inChannel.read(buf); //读入缓冲区。

以下是一个Buffer通过put()方法将数据写入的示例:

buf.put(127);

该put()方法还有许多其他版本,可让您以Buffer多种不同方式将数据写入 。例如,在特定位置写入或将字节数组写入缓冲区。有关更多详细信息,请参见JavaDoc以获取具体的缓冲区实现。

flip()方法

该flip()方法将Buffer从写入模式切换到读取模式。调用flip()会将positionback设置为0,并将设置为limit 刚才的位置。

换句话说,position现在标记读取位置,并limit标记将多少字节,字符等写入缓冲区-可以读取多少字节,字符等的限制。

6 从Buffer读取数据

您可以通过两种方式从读取数据Buffer。

从缓冲区读取数据到通道Channel。

使用get() 方法从缓冲区读取数据。

以下是如何从缓冲区将数据读取到通道的示例:

//从缓冲区读取到通道。

int bytesWritten = inChannel.write(buf);

以下是Buffer使用get()方法读取数据的示例:

byte aByte = buf.get();

get()方法还有许多其他版本,可让您以Buffer多种不同方式从中读取数据 。例如,在特定位置读取或从缓冲区读取字节数组。有关更多详细信息,请参见JavaDoc以获取具体的缓冲区实现。

rewind()

该Buffer.rewind()套position回0,这样你就可以重新读取缓冲区中的所有数据。在limit保持不变,因此仍标记,可以从被读取许多元素(字节,字符等)如何Buffer。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值