龙空技术网

Java NIO缓冲区

JAVA茶杯会 343

前言:

而今同学们对“java缓冲区的大小”可能比较讲究,朋友们都需要剖析一些“java缓冲区的大小”的相关资讯。那么小编同时在网络上收集了一些对于“java缓冲区的大小””的相关文章,希望咱们能喜欢,大家一起来学习一下吧!

与NIO通道交互时使用Java NIO缓冲区。 如您所知,数据从通道读入缓冲区,并从缓冲区写入通道。

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

基本缓冲区的使用

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

1.将数据写入缓冲区

2.调用buffer.flip()

3.从缓冲区读取数据

4.调用buffer.clear()或buffer.compact()

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

读完所有数据后,您需要清除缓冲区,使其准备好再次写入。 你可以通过两种方式来做到这一点:通过调用clear()或通过调用compact()。 clear()方法清除整个缓冲区。 compact()方法只会清除已读取的数据。 任何未读数据将被移动到缓冲区的开始处,并且数据将在未读数据之后写入缓冲区。

下面是一个简单的Buffer使用示例,其中写入,翻转,读取和清除操作以粗体显示:

RandomAccessFile aFile = new RandomAccessFile("data/nio-data.txt", "rw");FileChannel inChannel = aFile.getChannel();//创建容量为48字节的缓冲区ByteBuffer buf = ByteBuffer.allocate(48);int bytesRead = inChannel.read(buf); //读入缓冲区。while (bytesRead != -1) { buf.flip(); //使缓冲区准备好读取。while(buf.hasRemaining()){System.out.print((char) buf.get()); // 一次读取1个字节} buf.clear(); //使缓冲区准备好写入bytesRead = inChannel.read(buf);}aFile.close();

缓冲容量,位置和限制

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

缓冲区有三个你需要熟悉的属性,以便了解缓冲区的工作原理。 这些是:

capacity (容量)

position (位置)

limit (限制)

位置和限制的含义取决于缓冲区是处于读取还是写入模式。 无论缓冲模式如何,容量总是意味着相同。

以下是写入和读取模式下容量,位置和限制的说明。 解释如下图所示。

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

容量

作为一个内存块,Buffer具有一定的大小,也称为“容量”。 您只能将容量字节,长整数,字符等写入缓冲区。 一旦缓冲区已满,您需要将其清空(读取数据或清除数据),然后才能向其中写入更多数据。

位置

当您将数据写入缓冲区时,您可以在某个位置执行此操作。 最初的位置为0.当一个字节,长字符等被写入缓冲区时,位置会前进到指向缓冲区中的下一个单元以插入数据。 职位可以最大限度地成为能力 - 1。

当你从缓冲区读取数据时,你也可以从给定的位置进行读取。 当您将缓冲区从写入模式翻转到读取模式时,位置将重置为0.当您从缓冲区中读取数据时,您可以从位置读取数据,并且位置会前进到下一个读取位置。

限制

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

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

缓冲区类型

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

ByteBuffer (字节缓冲区)

MappedByteBuffer (映射字节缓冲区)

CharBuffer (字符缓冲区)

DoubleBuffer (双缓冲区)

FloatBuffer (浮动缓冲区)

IntBuffer (整型缓冲区)

LongBuffer (长缓整型冲区)

ShortBuffer (短整型缓冲区)

如您所见,这些Buffer类型表示不同的数据类型。 换句话说,它们允许您使用char,short,int,long,float或double来处理缓冲区中的字节。

MappedByteBuffer有点特别,并且将在另一篇独立文章中进行重点介绍。

分配一个缓冲区

要获得一个Buffer对象,你必须首先分配它。 每个Buffer类都有一个allocate()方法来做到这一点。 以下是一个显示ByteBuffer分配的示例,容量为48个字节:

ByteBuffer buf = ByteBuffer.allocate(48);

下面是一个分配CharBuffer的例子,其空间为1024个字符:

CharBuffer buf = CharBuffer.allocate(1024);

将数据写入缓冲区

您可以通过两种方式将数据写入缓冲区:

1.将数据从通道写入缓冲区

2.通过缓冲区的put()方法自己将数据写入缓冲区。

以下是一个示例,显示通道如何将数据写入缓冲区:

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

这是一个通过put()方法将数据写入缓冲区的示例:

buf.put(127);

还有很多其他版本的put()方法,允许您以许多不同的方式将数据写入缓冲区。 例如,写在特定的位置,或者将一个字节数组写入缓冲区。 有关更多详细信息,请参阅具体缓冲区实现的JavaDoc。

flip()

flip()方法将Buffer从写入模式切换到读取模式。 调用flip()会将位置设置回0,并将限制设置到刚刚位置的位置。

换句话说,位置现在标记为读取位置,限制标记有多少个字节,字符等被写入缓冲区 - 可以读取的字节数,字节数等限制。

从缓冲区读取数据

有两种方法可以从缓冲区中读取数据。

1.将数据从缓冲区读入通道。

2.使用其中一个get()方法自己从缓冲区中读取数据。

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

//从缓冲区读入通道int bytesWritten = inChannel.write(buf);

这是一个使用get()方法从Buffer读取数据的示例:

byte aByte = buf.get();

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

rewind()

Buffer.rewind()将位置设置回0,这样您可以重新读取缓冲区中的所有数据。 该限制保持不变,因此仍然标记可以从缓冲区读取多少个元素(字节,字符等)。

clear()和compact()

一旦完成从Buffer中读取数据,您必须使缓冲区准备好再次写入。你可以通过调用clear()或者通过调用compact()来完成。

如果您调用clear(),则该位置将设置回0并限制容量。换句话说,缓冲区被清除。缓冲区中的数据未被清除。只有标记告诉您可以将数据写入缓冲区的位置。

如果在调用clear()时缓冲区中存在未读取的数据,那么数据将被“忘记”,这意味着您不再有任何标记来指示已读取的数据以及未读取的数据。

如果Buffer中仍有未读数据,并且您想稍后阅读它,但需要先写一些内容,请调用compact()而不是clear()。

compact()将所有未读数据复制到缓冲区的开始处。然后它将位置设置在最后一个未读元素之后。极限属性仍然设置为容量,就像clear()一样。现在缓冲区已准备好写入,但不会覆盖未读数据。

mark() and reset()

您可以通过调用Buffer.mark()方法在Buffer中标记给定的位置。 然后您可以通过调用Buffer.reset()方法将位置重置回标记的位置。 这里是一个例子:

buffer.mark();//多次调用buffer.get(),例如 在解析过程中。buffer.reset(); //设置位置回到标记。

equals() and compareTo()

可以使用equals()和compareTo()比较两个缓冲区。

equals()

如果二个缓冲区是equals:

1.它们是相同的类型(byte,char,int等)

2.它们在缓冲区中具有相同数量的剩余字节,字符等。

3.所有剩余的字节,字符等是相等的。

正如你所看到的,equals只比较缓冲区的一部分,而不是它内部的每一个元素。 实际上,它只是比较缓冲区中的其余元素。

compareTo()

compareTo()方法比较两个缓冲区的其余元素(字节,字符等),用于例如 排序例程。 在下列情况下,缓冲区被认为比另一个缓冲区“小”:

1.第一个元素等于另一个缓冲区中的对应元素,小于另一个缓冲区中的元素。

2.所有的元素都是相等的,但第一个缓冲区在第二个缓冲区之前耗尽元素(元素较少)。

标签: #java缓冲区的大小