在java新IO中,所有的操作都是以缓冲区进行的,既然使用了缓冲区,则操作的性能是最高的。
各种数据类型的缓冲区类(是以基本数据类型为主的)
java.nio.ByteBuffer //存储字节的Buffer
java.nio.CharBuffer //存储字符的Buffer
java.nio.ShortBuffer //存储短整形的Buffer
java.nio.IntBuffer //存储整形的Buffer
java.nio.LongBuffer //存储长整形的Buffer
java.nio.FloatBuffer //存储单精度浮点型的Buffer
java.nio.DoubleBuffer //存储双精度浮点型的Buffer
他们都有直接的父类 - java.nio.Buffer
为甚么没有boolean类型的?因为不需要缓冲操作的说。。
缓冲区操作主要是以 几个变量为准来完成操作的。
position 、 limit 、 capacity(容量)
package buffdemo;
import java.nio.IntBuffer;
public class intBuffDemo01 {
public static void main(String[] args) {
IntBuffer buf = IntBuffer.allocate(10); //准备出10个大小的缓冲区
System.out.println("1 、 写入数据之前的 position limit 和capacity属性");
System.out.println("--> position = " + buf.position() + ", limit()" + buf.limit()
+ " , capacity : " + buf.capacity() );
int [] tmep = {1,5,7,9};
buf.put(3); //往缓冲区里放入一个数据
buf.put(tmep); //往缓冲区里放入一组数据
System.out.println("2 、 写入数据之后的 position limit 和capacity属性");
System.out.println("--> position = " + buf.position() + ", limit()" + buf.limit()
+ " , capacity : " + buf.capacity());
buf.flip(); //重设缓冲区:重设后,position(指针变为0,),limit=原来的position
System.out.println("3、 准备输出数据的 position limit 和capacity属性");
System.out.println("--> position = " + buf.position() + ", limit()" + buf.limit()
+ " , capacity : " + buf.capacity());
while(buf.hasRemaining()){ //此方法判断当前缓冲区的指针位置是否有数据,有则返回true,迭代输出
int x = buf.get();
System.out.print(x + "、");
}
}
}
输出结果:
1 、 写入数据之前的 position limit 和capacity属性 --> position = 0, limit()10 , capacity : 10 2 、 写入数据之后的 position limit 和capacity属性 --> position = 5, limit()10 , capacity : 10 3、 准备输出数据的 position limit 和capacity属性 --> position = 0, limit()5 , capacity : 10 内容: 3、1、5、7、9、 |
深入缓冲区操作:
在Buffer中存在一系列的状态变量,这些状态变量随着写入或du读取都有可能被改变,在缓冲区可以使用三个值表示缓冲区的状态:
★ postiion :表示下一个缓冲区读取或写入的操作指针,每次向缓冲区写入数据的时候指针就会改变,指针永远放在写入的最后一个元素之后。注:如果写入4个位置的数据,则position会在第五个位置。
★ limit : 表示还有多谢数据需要存储或读取,positon<=limit
★ capacity :表示缓冲区的最大容量,limit<=capacity:表示缓冲区的最大容量,此值在分配缓冲区时被设置,一般不会更改。
slice();方法可以返回一个子缓冲区,使用这个的话得设置好 limit和position
修改 position 和 limit划分子缓冲区
子缓冲区和缓冲区共享数据,所以当子缓冲区发生变化时,主缓冲区也一并改变了。
如果希望创建的缓冲区不希望被修改,则可以创建只读缓冲区
代码: InteBuffer sub = buf.asReadyOnlyBuffer();
package buffdemo;
import java.nio.IntBuffer;
public class intBuffDemo02 {
public static void main(String[] args) {
IntBuffer buf = IntBuffer.allocate(10); //准备出10个大小的缓冲区
IntBuffer sub = null;
for(int i=0;i<10;i++){
buf.put(i * 2 + 1);
}
sub = buf.asReadOnlyBuffer(); //创建只读缓冲区
sub.flip(); //把只读缓冲区的指针重置
//此处操作根据filp()的特性进行了重置position=0,limit=2(原来的position大小)
System.out.println("子缓冲区的内容");
while(sub.hasRemaining()){ //此方法判断当前缓冲区的指针位置是否有数据,有则返回true,迭代输出
int x = sub.get();
System.out.print(x + "、");
}
sub.put(7,30); //错误 ,只读缓冲区不能被修改
}
}
直接缓冲区 : allocateDirect(int capacity)
在ByteBuffer 类中的一个方法返回:
操作方法和第一个相同,当性能更高,因为当创建此种缓冲区的时候,JVM会尽可能的完成任务。
总结:
1、NIO都是以缓冲区进行操作的
2、缓冲区都是针对基本数据类型实现的,除了boolean除外
3、缓冲区中存在postiion 、limit、capacity三个状态变量
4、缓冲区操作中通过方法 allocate()创建缓冲区,或使用只读、直接缓冲区。