传统的IO和NIO的区别:
传统的IO是面向流,阻塞式IO,单向的
NIO:基于通道的,通道内的缓冲区,双向的,非阻塞的,有选择器
通道和缓冲区
通道表示要打开的IO设备(文件/套接字)的连接,需要使用NIO系统,需要获取用于连接IO设备的通道以及用于容纳数据的缓冲区,然后操作缓冲区对数据进行处理
总:channel负责传输,Buffer负责存储
缓冲区
负责数据的存取,缓冲区是数组,用于存储不同的数据类型的数据
根据数据类型的不同(Boolean 除外),提供了相应类型的缓冲区:
ByteBuffer,CharBuffer,ShortBuffer,IntBuffer,LongBuffer,FloatBuffer,DoubleBuffer
上述缓冲区的管理方式几乎一致,通过allocate()获取缓冲区
缓存区中的两个核心方法
put() : 存入数据到缓冲区中
get() : 获取缓冲区中的数据
缓冲区汇中的四个核心属性:
capacity : 容量,表示缓冲区中最大存储数据的容量,一旦声明不能改变
limit : 界限,表示缓冲区中可以操作数据的大小,(limit 后数据不能够读写操作)
position : 位置,表示缓冲区中正在操作数据的位置
mark : 标记,表示记录当前position的位置,可以通过reset()恢复到mark的位置
0 <= mark <= position <= limit <= capacity
@Test
public void test1() {
String str = "abcde";
//1 分配一个指定大小的缓冲区
ByteBuffer buf = ByteBuffer.allocate(1024);
System.out.println("------------allocate()-----------");
System.out.println(buf.position());
System.out.println(buf.limit());
System.out.println(buf.capacity());
/*
结果:
------------allocate()-----------
0
1024
1024
*/
//2 利用put() 存入数据到缓冲区中
buf.put(str.getBytes());
System.out.println("--------------put()---------------");
System.out.println(buf.position());
System.out.println(buf.limit());
System.out.println(buf.capacity());
/*
结果: 写数据的时候,容量没变,limit也没变
--------------put()---------------
5
1024
1024
*/
// 3 切换读取数据模式
buf.flip();
System.out.println("------------flip()------------");
System.out.println(buf.position());
System.out.println(buf.limit());
System.out.println(buf.capacity());
/*
------------put()------------
0
5
1024
*/
//4 利用get() 读取缓冲区中的数据
System.out.println("-------------get()-----------");
byte[] dst = new byte[buf.limit()];
buf.get(dst);
System.out.println(new String(dst,0,dst.length));
System.out.println("------------get()-------------");
System.out.println(buf.position());
System.out.println(buf.limit());
System.out.println(buf.capacity());
/*
------------get()-------------
5
5
1024
*/
//5. rewind():可以重复读取数据
buf.rewind();
System.out.println("----------------rewind()-------------");
System.out.println(buf.position());
System.out.println(buf.limit());
System.out.println(buf.capacity());
//6. clear() 清空缓冲区,但是缓冲区的数据仍然存在,但是处于"被遗忘"状态
buf.clear();
System.out.println("---------------clear()---------------");
System.out.println(buf.position());
System.out.println(buf.limit());
System.out.println(buf.capacity());
System.out.println((char) buf.get());
/*
---------------clear()---------------
0
1024
1024
a
*/
}
mark标记
@Test
public void test2(){
String str = "abcde";
ByteBuffer buf = ByteBuffer.allocate(1024);
buf.put(str.getBytes());
//切换到读模式
buf.flip();
byte[] dst = new byte[buf.limit()];
buf.get(dst,0,2);
System.out.println(new String(dst,0,2));
System.out.println(buf.position());
//mark():标记
buf.mark();
buf.get(dst,2,2);
System.out.println(buf.position());
//reset(): 恢复到mark的位置
buf.reset();
System.out.println(buf.position());
//判断缓冲区中是否还有剩余数据
if (buf.hasRemaining()){
//获取缓冲区中可以操作的数量
System.out.println(buf.remaining());
}
}
/*
ab
2
4
2
3
*/