"Java NIO (New Input/Output) 是Java平台的标准部分,提供了一种不同于传统I/O的高效方式来处理输入和输出操作。NIO的核心在于缓冲区(Buffer)和通道(Channel)的概念,以及非阻塞I/O的实现。本学习笔记主要探讨Java NIO的Buffer类和相关操作。
Buffer类是Java NIO中的基础抽象类,提供了对各种基本类型(如byte, char, int等)数据的存储和操作。Buffer类有以下特点和属性:
1. **容量(Capacity)**: 容量表示Buffer可以容纳的最大元素数量,一旦创建,容量不可改变。每个Buffer子类如ByteBuffer、CharBuffer等都有其特定的数据类型。
2. **限制(Limit)**: 限制指出了Buffer中最后一个不应读取或写入的元素的索引。限制不会超过容量,初始限制通常是容量。
3. **位置(Position)**: 位置表示下一个要读取或写入的元素的索引。位置不能为负,也不能超过限制。新创建的Buffer位置通常为0。
**数据传输**:
- **相对操作(Relative Operations)**: 这些操作从当前位置开始读取或写入元素,并根据传输的元素数量更新位置。如果尝试超出限制进行操作,会抛出异常。
- **绝对操作(Absolute Operations)**: 这些操作允许指定元素的索引进行读写,而不影响位置。如果索引超出限制,也会抛出异常。
**标记和重置(Marking and Resetting)**:
- **标记(Mark)**: 可以在Buffer上设置一个标记,之后可以通过`reset()`方法返回到这个标记的索引。如果未设置标记,`reset()`会抛出异常。
- **重置(Reset)**: `reset()`方法将位置设回之前设置的标记,前提是标记已被定义。
**不变式.Invariant**:
Buffer的标记、位置、限制和容量必须满足以下条件:0 <= 标记 <= 位置 <= 限制 <= 容量
除了基本的访问属性和标记重置的方法,Buffer还提供了以下操作:
- **清除(Clear)**: 清除Buffer的内容,但不改变其容量、限制和位置。位置被设回0,限制保持不变,内容变为未定义。
- **反转(Flip)**: 将Buffer从写模式切换到读模式,通过设置限制为当前位置并把位置设回0完成。
- **rewind**:将位置设回0,保留当前限制,允许重新读取已存入的数据。
在实际应用中,NIO的Buffer类常与Channel配合使用,用于从Channel读取数据到Buffer,或者将Buffer中的数据写入到Channel。例如,FileChannel可以从文件读取数据到ByteBuffer,或者将ByteBuffer中的数据写入文件。此外,NIO的Selector机制允许单个线程同时处理多个Channel,提高了并发I/O的效率。
Java NIO的Buffer类提供了一种高效、灵活的方式来处理数据,它的设计考虑到了多种操作场景,包括数据的读写、标记重置以及不同I/O操作间的转换。了解并熟练使用Buffer,可以显著提升Java程序在I/O操作上的性能。"