`
youyu4
  • 浏览: 440129 次
社区版块
存档分类
最新评论

java NIO 之 Buffer

 
阅读更多

java NIO 之 Buffer

 

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

 

缓冲区本质上是一块可以写入数据,然后可以从中读取数据的内存。这块内存被包装成NIO Buffer对象,并提供了一组方法,用来方便的访问该块内存。

 

 

 

Buffer的基本用法

 

Buffer读写数据的步骤:

 

  1. 写入数据到Buffer
  2. 调用flip()方法
  3. 从Buffer中读取数据
  4. 调用clear()方法或者compact()方法

      当向buffer写入数据时,buffer会记录下写了多少数据。一旦要读取数据,需要通过flip()方法将Buffer从写模式切换到读模式。在读模式下,可以读取之前写入到buffer的所有数据。

 

      一旦读完了所有的数据,就需要清空缓冲区,让它可以再次被写入。有两种方式能清空缓冲区:调用clear()或compact()方法。clear()方法会清空整个缓冲区。compact()方法只会清除已经读过的数据。任何未读的数据都被移到缓冲区的起始处,新写入的数据将放到缓冲区未读数据的后面。

 

代码:

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

 

 

 

 

Buffer的 capacity , position 和 limit

 

缓冲区本质上是一块可以写入数据,然后可以从中读取数据的内存。这块内存被包装成NIO Buffer对象,并提供了一组方法,用来方便的访问该块内存。

 

为了理解Buffer的工作原理,需要熟悉它的三个属性:

 

  • capacity
  • position
  • limit

position和limit的含义取决于Buffer处在读模式还是写模式。不管Buffer处在什么模式,capacity的含义总是一样的。


        

 

 

capacity(Buffer的空间大小)

 

      作为一个内存块,Buffer有一个固定的大小值,也叫“capacity”.你只能往里写capacity个byte、long,char等类型。一旦Buffer满了,需要将其清空(通过读数据或者清除数据)才能继续写数据往里写数据。

 

 

position(Buffer中可用空间的位置)

 

      当你写数据到Buffer中时,position表示当前的位置。初始的position值为0.当一个byte、long等数据写到Buffer后, position会向前移动到下一个可插入数据的Buffer单元。position最大可为capacity – 1.

 

 

limit

 

在写模式时,Buffer的limit表示你最多能往Buffer里写多少数据。 写模式下,limit等于Buffer的capacity。

 

在读模式时,limit表示你最多能读到多少数据。因此,当切换Buffer到读模式时,limit会被设置成写模式下的position值。换句话说,你能读到之前写入的所有数据(limit被设置成已写数据的数量,这个值在写模式下就是position)

 

 

 

 

Buffer的类型

 

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

Buffer类型代表了不同的数据类型。换句话说,就是可以通过char,short,int,long,float 或 double类型来操作缓冲区中的字节。

 

 

 

 

Buffer的分配

 

要想获得一个Buffer对象首先要进行分配。 每一个Buffer类都有一个allocate方法。下面是一个分配48字节capacity的ByteBuffer的例子。

 

ByteBuffer buf = ByteBuffer.allocate(48);
 

 

这是分配一个可存储1024个字符的CharBuffer:

 

CharBuffer buf = CharBuffer.allocate(1024);
 

 

 

 

 

向Buffer中写数据

 

写数据到Buffer有两种方式:

 

  • 从Channel写到Buffer
  • 通过Buffer的put()方法写到Buffer里

 

从Channel写到Buffer的例子

 

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

 

 

通过put方法写Buffer的例子

 

buf.put(127);
    put方法有很多版本,允许你以不同的方式把数据写入到Buffer中。例如, 写到一个指定的位置,或者把一个字节数组写入到Buffer。 更多Buffer实现的细节参考JavaDoc。

 

 

 

flip()方法

 

flip方法将Buffer从写模式切换到读模式。调用flip()方法会将position设回0,并将limit设置成之前position的值。

 

换句话说,position现在用于标记读的位置,limit表示之前写进了多少个byte、char等 —— 现在能读取多少个byte、char等。

 

 

 

 

从Buffer中读取数据

 

从Buffer中读取数据有两种方式:

 

  • 从Buffer读取数据到Channel
  • 使用get()方法从Buffer中读取数据

 

从Buffer读取数据到Channel的例子

 

//read from buffer into channel.
int bytesWritten = inChannel.write(buf);
 

 

 

使用get()方法从Buffer中读取数据的例子

 

byte aByte = buf.get();
    get方法有很多版本,允许你以不同的方式从Buffer中读取数据。例如,从指定position读取,或者从Buffer中读取数据到字节数组。更多Buffer实现的细节参考JavaDoc。

 

 

 

 

 

rewind()方法

 

Buffer.rewind()将position设回0,所以你可以重读Buffer中的所有数据。limit保持不变,仍然表示能从Buffer中读取多少个元素(byte、char等)。

 

 

 

 

clear()与compact()方法

 

一旦读完Buffer中的数据,需要让Buffer准备好再次被写入。可以通过clear()或compact()方法来完成。

 

   1. 如果调用的是clear()方法,position将被设回0,limit被设置成 capacity的值。换句话说,Buffer 被清空了。Buffer中的数据并未清除,只是这些标记告诉我们可以从哪里开始往Buffer里写数据。

 

   2. 如果Buffer中有一些未读的数据,调用clear()方法,数据将“被遗忘”,意味着不再有任何标记会告诉你哪些数据被读过,哪些还没有。

 

   3. 如果Buffer中仍有未读的数据,且后续还需要这些数据,但是此时想要先先写些数据,那么使用compact()方法。

 

   4. compact()方法将所有未读的数据拷贝到Buffer起始处。然后将position设到最后一个未读元素正后面。limit属性依然像clear()方法一样,设置成capacity。现在Buffer准备好写数据了,但是不会覆盖未读的数据。

 

 

 

 

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.

 

 

 

 

equals()与compareTo()方法

 

可以使用equals()和compareTo()方法两个Buffer。

 

 

equals()

 

当满足下列条件时,表示两个Buffer相等:

 

  • 有相同的类型(byte、char、int等)
  • Buffer中剩余的byte、char等的个数相等
  • Buffer中所有剩余的byte、char等都相同

 

如你所见,equals只是比较Buffer的一部分,不是每一个在它里面的元素都比较。实际上,它只比较Buffer中的剩余元素

 

 

compareTo()

 

compareTo()方法比较两个Buffer的剩余元素(byte、char等), 如果满足下列条件,则认为一个Buffer“小于”另一个Buffer:

 

  • 第一个不相等的元素小于另一个Buffer中对应的元素 。
  • 所有元素都相等,但第一个Buffer比另一个先耗尽(第一个Buffer的元素个数比另一个少)。

 

注意:剩余元素是从 position到limit之间的元素。

 

  • 大小: 15.8 KB
分享到:
评论

相关推荐

    详细了解JAVA NIO之Buffer(缓冲区)

    JAVA NIO之Buffer(缓冲区)详解 JAVA NIO之Buffer(缓冲区)是Java NIO中一个重要的概念,它提供了一种高效的数据处理方式。缓冲区是一个可以写入数据然后从中读取数据的内存块,它被包装成NIO Buffer对象,并...

    Java NIO实战开发多人聊天室

    12-Java NIO-Buffer-概述.mp4 13-Java NIO-Buffer-基本使用.mp4 14-Java NIO-Buffer-三个属性和类型.mp4 17-Java NIO-Buffer-缓冲区分片.mp4 18-Java NIO-Buffer-只读缓冲区.mp4 19-Java NIO-Buffer-直接缓冲区.mp4 ...

    JavaNIO chm帮助文档

    Java NIO系列教程(三) Buffer Java NIO系列教程(四) Scatter/Gather Java NIO系列教程(五) 通道之间的数据传输 Java NIO系列教程(六) Selector Java NIO系列教程(七) FileChannel Java NIO系列教程(八) ...

    Java NIO英文高清原版

    Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java平台中用于替代标准I/O(BIO)模型的一种新机制。NIO在Java 1.4版本引入,提供了更高效的数据处理和通道通信方式,特别适用于高并发、大数据...

    java NIO 视频教程

    标准的IO基于字节流和字符流进行操作的,而NIO是基于通道(Channel)和缓冲区(Buffer)进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中。 Java NIO: Non-blocking IO(非阻塞IO) Java NIO...

    java nio 包读取超大数据文件

    ### Java NIO 处理超大数据文件的知识点详解 #### 一、Java NIO简介 Java NIO(New IO)是Java平台上的新输入/输出流API,它提供了与传统IO(即Java IO)不同的数据处理方式。NIO在Java 1.4版本引入,并在后续版本...

    java NIO技巧及原理

    Java NIO(New Input/Output)是Java标准库提供的一种I/O模型,它与传统的 Blocking I/O(IO)相比,提供了更加高效的数据传输方式。在Java NIO中,"新"主要体现在非阻塞和多路复用这两个特性上,这使得NIO更适合于...

    Java NIO Socket基本

    缓冲区类型包括ByteBuffer、CharBuffer、IntBuffer、DoubleBuffer等,它们都继承自`java.nio.Buffer`。 3. **选择器(Selector)**:用于监听多个通道的事件(如连接就绪、数据到达等),当某个通道准备好进行读写...

    java NIO实例

    3. **Buffer(缓冲区)**:在NIO中,数据读写都是通过缓冲区进行的。缓冲区是一个可以容纳特定类型数据(如字节、字符、整数等)的容器,它提供了对数据的高效访问和管理。 4. **FileChannel**:用于文件的读写,...

    java nio 读文件

    Java NIO(New IO)是Java 1.4版本引入的一个新模块,它提供了一种不同于标准Java IO API的处理I/O操作的方式。NIO的主要特点是面向缓冲区,非阻塞I/O,以及选择器,这些特性使得NIO在处理大量并发连接时表现出更高...

    Java NIO Buffer过程详解

    Java NIO Buffer 过程详解 Java NIO Buffer 是 Java NIO 中的一种重要组件,负责数据的存储和传输。缓冲区是数组,用于存储不同数据类型的数据。在与 NIO 通道交互时,Java NIO Buffer plays a crucial role. 基本...

    java NIO详细教程

    Java NIO的核心组件包括Channel(通道)、Buffer(缓冲区)和Selector(选择器)。 - **Channel**:通道用于连接源和目的地,支持数据的读写操作。与传统的流不同,通道支持双向通信,并且可以通过非阻塞的方式进行...

    一个java NIO的例子

    Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java标准库提供的一种替代传统I/O模型的新技术。在传统的Java IO模型中,读写操作是阻塞的,即当调用read或write方法时,线程会等待数据准备好或...

    Java.NIO资源下载资源下载

    根据提供的文件信息,我们可以提取并总结出关于Java NIO(New Input/Output)的重要知识点。 ### Java NIO 概述 Java NIO 是 Java 平台的一个重要特性,首次出现在 Java 1.4 版本中。它为 Java 开发者提供了一套...

    java nio入门学习,两个pdf

    Java NIO定义了多个Buffer类,如ByteBuffer、CharBuffer、IntBuffer等,每个Buffer都有容量、位置、限制等属性,可以进行读写操作。 3. **选择器(Selectors)**:选择器用于监控多个通道的状态,当某个通道准备就绪...

    nio.rar_FastCopyFile.java_NIO_UseFloatBuffer.java_java nio_文件锁

    FloatBuffer是Java NIO中的一种Buffer类型,用于存储浮点数。它继承自ByteBuffer,并提供了对浮点数读写的支持。`UseFloatBuffer.java`可能包含如何分配、填充、反转、清理和获取浮点数的示例代码。在处理大量浮点数...

Global site tag (gtag.js) - Google Analytics