另外,与面向线程的,阻塞式IO方式相比,多道通信,非阻塞式IO机制可以更加有效的处理大量连接的应用程序。
新IO除了原有功能之外,还提供了以下新特性:
1.多路选择的,非阻塞式IO机制
2.支持文件锁及内存映射
3.支持正则表达式的模式匹配设施
4.字符集编码器和译码器
在新IO中通过使用Buffer和Channel支持以上特性。
Buffer(缓冲区)
在NIO中所有操作都需要使用缓冲区处理,所有的读写都是通过缓冲区来完成的,缓冲区是一个线性的,有序的数据集,只能存储基本数据类型。
关于Buffer类的常用方法,请查阅javadoc文档,这里不再一一列出,NIO中针对每一种基本数据类型都有一个相应的缓冲区操作类,包括(ByteBuffer,CharBuffer,ShortBuffer,IntBuffer,LongBuffer,FloatBuffer,DoubleBuffer),关于各缓冲区操作类的方法,请查阅javadoc文档。
1. Buffer的基本用法,代码如下:
package com.ray.nio.demo;
import java.nio.IntBuffer;
/**
* 缓冲区的基本操作
*
* 在Buffer中存在一系列状态变量,用于记录操作缓冲区内容的指针位置(position),指针的操作边界(limit),缓冲区大小(capacity)
* position:表示下一个操作(读/写)的指针,指针永远放在最后(读/写)入的数据位置之后
* limit:limit为定界position指针的操作边界,position<limit
* capacity:定义缓冲区大小
* 本示例程序操作步骤:
* 1.为IntBuffer开辟缓冲区
* 2.向缓冲区写入数据
* 3.调用flip方法,重设缓冲区 操作指针(position)、操作边界(limit)的位置
* 4.遍历缓冲区数据
*
* @author xuleilei
*
*/
public class IntBuffer01 {
public static void main(String[] args) {
IntBuffer intBuffer = IntBuffer.allocate(10);
System.out.println("未写入数据时的缓冲区:position:" + intBuffer.position() + ",limit:" + intBuffer.limit() + ",capacity:" + intBuffer.capacity());
int pre = 0,arrs[] = {1,3,5};
intBuffer.put(pre);
intBuffer.put(arrs);
// intBuffer.put(6, 9); 此处写入数据无效,确保缓冲区起始数据依次连续存储数据
System.out.println("写入数据后的缓冲区:position:" + intBuffer.position() + ",limit:" + intBuffer.limit() + ",capacity:" + intBuffer.capacity());
// 重设缓冲区,将
intBuffer.flip();
System.out.println("调用filp方法后的缓冲区:position:" + intBuffer.position() + ",limit:" + intBuffer.limit() + ",capacity:" + intBuffer.capacity());
// 读取缓冲区中的内容
// System.out.print(intBuffer.get(3));
while(intBuffer.hasRemaining()){
System.out.print(intBuffer.get() + "、");
}
}
}
2.创建子缓冲区
package com.ray.nio.demo;
import java.nio.IntBuffer;
/**
* 创建子缓冲区
*
* NIO中可以使用各缓冲区类的slice方法从一个缓冲区中创建一个子缓冲区,子缓冲区与原缓冲区共享数据
*
* @author xuleilei
*
*/
public class IntBuffer02 {
public static void main(String[] args) {
// 开辟缓冲区空间,声明子缓冲区
IntBuffer intBuffer = IntBuffer.allocate(10),subBuffer = null;
// 向缓冲区中填充数据,10个偶数
for(int i = 0;i < 10;i++){
intBuffer.put(i*2);
}
// 将缓冲区的position指针设置在第三个元素上,并设置边界为5
intBuffer.position(2);
intBuffer.limit(5);
// 开辟子缓冲区
subBuffer = intBuffer.slice();
// 修改子缓冲区数据
for(int i=0;i<subBuffer.capacity();i++){
subBuffer.put(subBuffer.get(i) - 1);
}
// 重设缓冲区
intBuffer.flip();
intBuffer.limit(intBuffer.capacity());
// 读取缓冲区中的内容
while(intBuffer.hasRemaining()){
System.out.print(intBuffer.get() + "、");
}
}
}
3.创建只读缓冲区
package com.ray.nio.demo;
import java.nio.IntBuffer;
/**
* 创建只读缓冲区
*
* 如果希望使用缓冲区的内容,但又不希望缓冲区内容被修改,则可以通过asReadOnlyBuffer创建一个只读缓冲区。
* 注意:创建后的只读缓冲区不能变为可写状态
* @author xuleilei
*
*/
public class IntBuffer03 {
public static void main(String[] args) {
IntBuffer intBuffer = IntBuffer.allocate(10);
IntBuffer intBufferReadOnly = null;
int pre = 0,arrs[] = {1,3,5};
intBuffer.put(pre);
intBuffer.put(arrs);
// 将缓冲区变为只读缓冲区,注意在转换为只读缓冲区之前,原缓冲区确保
intBufferReadOnly = intBuffer.asReadOnlyBuffer();
// 重设缓冲区
intBufferReadOnly.flip();
// 读取缓冲区中的内容
while(intBufferReadOnly.hasRemaining()){
System.out.print(intBufferReadOnly.get() + "、");
}
// 向只读缓冲区中写入数据,非法!!!
intBufferReadOnly.put(222);
}
}
4.创建直接缓冲区
关于NIO缓冲区的基本概念及使用先讲到这里,关于Channel的讲解,继续关注...