NIO技术的核心要点是:缓冲区(Buffer)
四个核心技术点,分别是:
capacity(容量):缓冲区的大小。
limit(限制):可以手动设置,默认为等于capacity,索引从0开始。
position(位置):可以手动设置,默认等于0。通常表示插入的起始位置。
mark(标记):调用reset方法可以回到标记的位置。
在此之上的重要方法,
表示剩余空间大小:remaining = limit - position。
输出常用的方法:
注意rewind,clear,flip的区别
rewind:postion = 0,mark = -1;
clear:position = 0,limit = capacity, mark = -1;
flip:position = 0, limit = position, mark = -1.
规则:
1)缓冲区的capacity不能为负数,缓冲区的limit不能为负数,缓冲区的position不能为负数。
2)position不能大于其capacity。
3)limit不能大于其capacity
4)如果定义了mark,则在将position或limit调整为小于该mark的值时,该mark被丢弃。
5)如果未定义mark,那么调用reset方法将会报错。
6)如果position大于新的limit,则position的值就是新的limit的值。
7)当limit=position时,在指定的position写入数据
相同点在于都是置position为0,只要区别就是limit的值的变化。
1.rewind的limit值不变,通常用来重新读取或写入数据。
2.clear使一切值都还原成初始状态
3.flip的limit等于position。通常用来截取缓冲区一部分内容
- 创建缓冲区的两种方式
因为Buffer和它的子类
1.ByteBuffer
2.CharBuffer
3.DoubleBuffer
4.FloatBuffer
5.IntBuffer
6.LongBuffer
7.ShortBuffer
全部都是抽象类,所以只能通过静态方法创建
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
public class CreateBuffer {
public static void main(String[] args){
//开辟固定空间大小的缓冲区
ByteBuffer byteBuffer = ByteBuffer.allocate(10);
//将数组放到缓冲区
char[] array = new char[]{'1','2','3'};
CharBuffer charBuffer = CharBuffer.wrap(array);
}
}
缓冲区的类别:间接缓冲区,直接缓冲区,只读缓冲区。
为什么间接缓冲区的类型叫做HeapByteBuffer而不叫做IndirectByteBuffer?
因为间接缓冲区中的间接指的就是JVM堆,JVM堆会在向缓冲区传数据的时候先复制硬盘的数据,然后缓冲区在从JVM堆中读取数据。注意:缓冲区也在JVM中。
public class BufferClass {
public static void main(String[] args){
ByteBuffer byteBuffer = ByteBuffer.allocate(10); //间接缓冲区
ByteBuffer byteBuffer1 = ByteBuffer.allocateDirect(10); //直接缓冲区
ByteBuffer byteBuffer2 = byteBuffer.asReadOnlyBuffer(); //只读缓冲区
System.out.println(byteBuffer);
System.out.println(byteBuffer1);
}
}
缓冲区之间的转换:long = double = 8个字节;int = float = 4个字节;short = char = 2个字节。缓冲区的内容更改是相互的,但是限制和标记值是相互独立
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.DoubleBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.LongBuffer;
import java.nio.ShortBuffer;
public class BufferClass {
public static void main(String[] args){
ByteBuffer byteBuffer = ByteBuffer.allocate(10);
CharBuffer charBuffer = byteBuffer.asCharBuffer();
System.out.println("charBuffer.capacity="+charBuffer.capacity());
ShortBuffer shortBuffer = byteBuffer.asShortBuffer();
System.out.println("shortBuffer.capacity="+shortBuffer.capacity());
IntBuffer intBuffer = byteBuffer.asIntBuffer();
System.out.println("intBuffer.capacity="+intBuffer.capacity());
FloatBuffer floatBuffer = byteBuffer.asFloatBuffer();
System.out.println("floatBuffer.capacity="+floatBuffer.capacity());
DoubleBuffer doubleBuffer = byteBuffer.asDoubleBuffer();
System.out.println("doubleBuffer.capacity="+doubleBuffer.capacity());
LongBuffer longBuffer = byteBuffer.asLongBuffer();
System.out.println("longBuffer.capacity=="+longBuffer.capacity());
}
}
复制缓冲区也有两种:
1.duplicate()方法用于创建一个与原始缓冲区共享内容的新缓冲区。新缓冲区的position,limit,mark和capacity都初始化为原始缓冲区的索引值,然而,它们的这些值是相互独立的。
2.slice()方法用于创建一个共享了原始缓冲区子序列的新缓冲区。新缓冲区的position值是0,而其limit和capacity的值都等于原始缓冲区的limit和position的差值。slice()方法将新缓冲区数组的offset值设置为原始缓冲区的position值,然而,在新缓冲区上调用array()方法还是会返回整个数组
import java.nio.ByteBuffer;
public class DeplicateAndSlice {
public static void main(String[] args) {
byte[] byteArray = {1,2,3,4,5};
ByteBuffer byteBuffer1 = ByteBuffer.wrap(byteArray);
byteBuffer1.position(2);
ByteBuffer byteBuffer2 = byteBuffer1.duplicate();
ByteBuffer byteBuffer3 = byteBuffer1.slice();
System.out.println("byteBuffer2.position="+byteBuffer2.position()+"\n"+
"byteBuffer2.limit="+byteBuffer2.limit());
System.out.println("byteBuffer3.position="+byteBuffer3.position()+"\n"+
"byteBuffer3.limit="+byteBuffer3.limit());
}
}