JAVA NIO Buffer的学习

JAVA NIO Buffer的学习

定义:缓冲区的工作与通道紧密联系。通道是I/O传输发生时通过的入口,而缓冲区是这些数据传输的来源或目标。简单来说buffer就是一块存储区域,其内部的存储是通过基本类型的数组来实现的。
下图是Buffer类的层次图:
缓冲区基础:概念上,缓冲区是包在一个对象内的基本数据元素数组。Buffer类相比一个简单数组的优点是它将关于数据的数据内容和信息包含在一个单一的对象中。Buffer类以及它专有的子类定义了一个用于处理数据缓冲区的API。
  1. 属性 
    缓冲区的四个属性(capacity、limit、position、mark)
    容量(Capacity) 缓冲区能够容纳的数据元素的最大数量。这一容量在缓冲区创建时被设定,并且永远不能被改变。
    上界(Limit) 缓冲区的第一个不能被读或写的元素。或者说,缓冲区中现存元素的计数。
    位置(Position) 下一个要被读或写的元素的索引。位置会自动由相应的get( )和put( )函数更新。
    标记(Mark) 一个备忘位置。调用mark( )来设定mark = postion。调用reset( )设定position = mark。标记在设定前是未定义的(undefined)。
    这四个属性之间总是遵循以下关系: 0 <= mark <= position <= limit <= capacity
  2. 缓冲区API
2.1 创建
ByteBuffer allocate(int capacity);
       ByteBuffer byteBuffer = ByteBuffer.allocate(10);
      新创建的ByteBuffer逻辑视图如下
2.2、填充
byteBuffer.put((byte)'H').put((byte)'E').put((byte)'L').put((byte)'L').put((byte)'O');
五次调用put()之后的缓冲区如图, 在GBK编码中,一个英文字符用一个字节表示,所以存储效果如下,此时mark=-1,position=5,limit=10,capcity=10
2. 3、翻转
Flip()函数将一个能够继续添加数据元素的填充状态的缓冲区翻转成一个准备读出元素的释放状态。
调用flip()方法,切换为读就绪状态 ,调用flip()方法后缓冲区如图
2.4、读取
System.out.println((char)byteBuffer.get());
System.out.println((char)byteBuffer.get());
读取后缓存区如图:
2.5、压缩
释放已读数据的空间,准备重新填充缓存区
调用compact方法后,缓冲区如图
 注意观察数组中元素的变化,实际上进行了数组拷贝,抛弃了已读字节元素,保留了未读字节元素;
2.6、标记
mark()方法调用时使标记被设为当前位置position的值,reset()函数设置position的值为当前的标记位置mark,
		ByteBuffer byteBuffer = ByteBuffer.allocate(10);
		byteBuffer.put((byte)'H').put((byte)'E').put((byte)'L').put((byte)'L').put((byte)'O');
		byteBuffer.flip();
		byteBuffer.position(3).mark().position(5).reset();
		System.out.println(byteBuffer.position());
这段代码执行后缓冲区情况如下:
2.7、清除
clear()方法被调用时将清除缓冲区,设置position = 0;       limit = capacity;       mark = -1;但并没有擦除缓冲区中的数据
		ByteBuffer byteBuffer = ByteBuffer.allocate(10);
		byteBuffer.put((byte)'H').put((byte)'E').put((byte)'L').put((byte)'L').put((byte)'O');
		byteBuffer.flip();
		System.out.println((char)byteBuffer.get());
		System.out.println((char)byteBuffer.get());
		byteBuffer.clear();
		System.out.println(byteBuffer.position());
		System.out.println(byteBuffer.limit());
这段代码执行后,缓冲区如图
2.8、倒带
rewind()方法倒带缓冲区,设置position=0,mark=-1,rewind方法可用与重复读写缓冲区。
		ByteBuffer byteBuffer = ByteBuffer.allocate(10);
		byteBuffer.put((byte)'H').put((byte)'E').put((byte)'L').put((byte)'L').put((byte)'O');
		byteBuffer.flip();
		System.out.println((char)byteBuffer.get());
		System.out.println((char)byteBuffer.get());
		byteBuffer.rewind();
这段代码执行后,缓冲区如图
常用的buffer  API就这几个,要想更深刻理解这些API还是阅读源码,然后自己写代码实践下。

参考资料: 《Java NIO》
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java NIO(New I/O)是一个可以替代标准 Java I/O API 的 Java API。NIO 提供了更快速、更高效的 I/O 操作方式,也可以进行非阻塞 I/O 操作。 下面是几个 NIO 核心类和接口: - Buffer:缓冲区,用于数据的读取和写入。 - Channel:通道,用于数据的读取和写入。 - Selector:选择器,用于监控多个通道的 I/O 状态,从而实现多路复用。 下面介绍一下 NIO 的主要操作步骤: 1. 创建 Buffer 对象:创建一个 Buffer 对象,用于存储数据。 2. 创建 Channel 对象:创建一个 Channel 对象,用于读取和写入数据。 3. 打开 Channel:打开一个 Channel 对象,并连接到指定的服务器。 4. 将数据写入 Buffer:将需要写入的数据写入到 Buffer 。 5. 切换 Buffer 模式:将 Buffer 从写模式切换到读模式。 6. 从 Buffer 读取数据:从 Buffer 读取数据。 7. 关闭 Channel:关闭 Channel 对象。 8. 关闭 Selector:关闭 Selector 对象。 下面是一个简单的 NIO 例子: ```java import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; public class NIOClient { public static void main(String[] args) throws IOException { SocketChannel socketChannel = SocketChannel.open(); socketChannel.connect(new InetSocketAddress("localhost", 8888)); ByteBuffer buffer = ByteBuffer.allocate(1024); buffer.put("Hello, server!".getBytes()); buffer.flip(); socketChannel.write(buffer); buffer.clear(); int num = socketChannel.read(buffer); System.out.println("Received from server: " + new String(buffer.array(), 0, num)); socketChannel.close(); } } ``` 这个例子,我们先创建了一个 SocketChannel 对象,并连接到指定的服务器。然后,我们创建了一个 ByteBuffer 对象,将需要写入的数据写入到 ByteBuffer ,切换 ByteBuffer 的模式,从读取数据并输出到控制台,最后关闭 SocketChannel 对象。 希望这份简单的介绍能够帮助你更好的了解 Java NIO API。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值