博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java NIO缓冲区(Buffer)(3)
阅读量:6156 次
发布时间:2019-06-21

本文共 3314 字,大约阅读时间需要 11 分钟。

Java NIO中的Buffer用于和NIO通道进行交互。

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

Buffer的基本用法

使用Buffer读写数据一般遵循以下四个步骤:

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

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

读完缓冲区中所有数据后,需要清空缓冲区,让它可以再次被写入。其清空方式有两种:调用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();

Buffer的capacity,position和limit

Buffer的三个属性:

  • capacity
  • position
  • limit

 

capacity

作为一个内存块,Buffer有一个固定的大小值“capacity”,你只能往里写capacity个byte、long,char等类型。一旦Buffer写满,需要将其清空才能继续写数据往里写数据。

position

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

将Buffer从写模式切换到读模式,position会被重置为0。当从Buffer读取一个数据后,position会向前移动到下一个可读的位置。

limit

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

当切换Buffer到读模式时,limit会被设置成写模式下的position值, 表示最多能读到多少数据。

Buffer的类型

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

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

Buffer的分配

要想获得一个Buffer对象首先要进行分配。 每一个Buffer类都有一个allocate方法。

ByteBuffer buf = ByteBuffer.allocate(48);//分配48字节capacity的ByteBuffer

CharBuffer buf = CharBuffer.allocate(
1024
);//分配一个可存储1024个字符的CharBuffer
 

向Buffer中写数据

写数据到Buffer有两种方式:

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

从Channel写到Buffer中:

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

通过put方法写Buffer中:

 buf.put(127);

注:put方法有很多版本,允许以不同的方式把数据写入到Buffer中。

从Buffer中读取数据

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

  1. 从Buffer读取数据到Channel。
  2. 使用get()方法从Buffer中读取数据。

从Buffer读取数据到Channel中:

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

使用get()方法从Buffer中读取数据:

 byte aByte = buf.get();

注:get方法有很多版本,允许以不同的方式从Buffer中读取数据。例如,从指定position读取,或者从Buffer中读取数据到字节数组。

flip()方法

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

rewind()方法

Buffer.rewind()方法会将position设回0,这样可以重读Buffer中的所有数据。limit保持不变,仍然表示能从Buffer中读取多少个元素。

clear()与compact()方法

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

调用clear()方法,未读数据将“被遗忘”,position将被设回0,limit被设置成 capacity的值。此时的Buffer 被清空,Buffer中的数据并未清除,写入数据时会覆盖未读数据。

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

mark()与reset()方法

调用Buffer.mark()方法,可以标记Buffer中的一个特定position。之后调用Buffer.reset()方法即可恢复到这个position。

例如:

buffer.mark(); //例如在解析期间多次调用buffer.get() buffer.reset();  //设定位置回到标记.

equals()与compareTo()方法

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

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

equals()方法

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

  1. 有相同的类型(byte、char、int等)。
  2. Buffer中剩余的byte、char等的个数相等。
  3. Buffer中所有剩余的byte、char等都相同。

equals只比较Buffer中的剩余元素,不是比较每一个在它里面的元素。

compareTo()方法

如果满足下列条件,则认为一个Buffer“小于”另一个Buffer:

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

转载于:https://www.cnblogs.com/chen970826/p/10938883.html

你可能感兴趣的文章
LogicalDOC 6.6.2 发布,文档管理系统
查看>>
给PowerShell脚本传递参数
查看>>
实战2——Hadoop的日志分析
查看>>
利用FIFO进行文件拷贝一例
查看>>
Ecshop安装过程中的的问题:cls_image::gd_version()和不支持JPEG
查看>>
resmgr:cpu quantum等待事件
查看>>
一个屌丝程序猿的人生(六十六)
查看>>
Java 编码 UTF-8
查看>>
SpringMVC实战(注解)
查看>>
关于静态属性和静态函数
查看>>
进程的基本属性:进程ID、父进程ID、进程组ID、会话和控制终端
查看>>
spring+jotm+ibatis+mysql实现JTA分布式事务
查看>>
MyBatis启动:MapperStatement创建
查看>>
调查问卷相关
查看>>
eclipse启动无响应,老是加载不了revert resources,或停留在Loading workbench状态
查看>>
1. Git-2.12.0-64-bit .exe下载
查看>>
怎样关闭“粘滞键”?
查看>>
[转]React 教程
查看>>
拓扑排序介绍
查看>>
eclipse打开工作空间(workspace)没有任务反应
查看>>