Java NIO 是从Java 1.4版本开始引入的一个新的IO API,可以替代标准的Java IO API。NIO与原来的IO有同样的作用和目的,但是使用的方式完全不同,NIO支持面向缓冲区的、基于通道的IO操作。NIO将以更加高效的方式进行文件的读写操作。
Java NIO 与 IO的主要区别:
IO NIO
面向流 面向缓冲区
阻塞IO(Blocking IO) 非阻塞IO(Non Blocking IO)
无 选择器
Java NIO系统的核心在于:通道(Channel)和缓冲区(Buffer)。Channel负责传输,Buffer负责存储
import java.nio.ByteBuffer;
/*
* 一、缓冲区(Buffer): 在Java NIO中负责数据的存取。缓冲区就是数组。用于存储不同数据类型的数据
* 根据数据类型不同(boolean 除外),提供了相应类型的缓冲区:
* ByteBuffer CharBuffer ShortBuffer IntBuffer LongBuffer FloatBuffer DoubleBuffer
*
* 上述缓冲区的管理方式几乎一致,通过allocate()获取缓冲区
*
* 二、缓冲区存取数据的两个核心方法:
* put(): 存入数据到缓冲区中
* get(): 获取缓冲区中的数据
*
* 三、缓冲区中的四个核心属性:
* capacity:容量,表示缓冲区中最大存储数据的容量。一旦声明不能改变。
* limit: 界限,表示缓冲区中可以操作数据的大小。(limit 后数据不能进行读写)
* position: 位置,表示缓冲区中正在操作数据的位置。
* mark: 标记,表示记录当前 position 的位置 ,可以通过reset() 恢复到mark的位置
*
* 0 <= mark <= position <= limit <= capacity
*
* ty
*
*/
public class Buffer {
public static void main(String[] args) {
String str = "abcde";
System.out.println(new String(str.getBytes(),1,2));
//1. 分配一个指定大小的缓冲区
ByteBuffer buf = ByteBuffer.allocate(1024);
System.out.println("---------------------");
System.out.println(buf.position());//即将要操作的位置
System.out.println(buf.limit());
System.out.println(buf.capacity());
//2. 利用 put() 存入数据到缓冲区中
buf.put(str.getBytes());
System.out.println("---------------------");
System.out.println(buf.position());
System.out.println(buf.limit());
System.out.println(buf.capacity());
//3. 切换到读取数据模式
buf.flip();
System.out.println("---------------------");
System.out.println(buf.position());
System.out.println(buf.limit());
System.out.println(buf.capacity());
//4. 利用 get() 读取缓冲区中的数据
byte[] dst = new byte[buf.limit()];
buf.get(dst);
System.out.println(new String(dst,0,dst.length));
System.out.println("---------------------");
System.out.println(buf.position());
System.out.println(buf.limit());
System.out.println(buf.capacity());
//5. rewind() 可重复读数据
buf.rewind();
System.out.println("---------------------");
System.out.println(buf.position());
System.out.println(buf.limit());
System.out.println(buf.capacity());
//6. clear(): 清空缓冲区,但是缓冲区中的数据依然存在,但是处于"被遗忘"状态
buf.clear();
System.out.println("---------------------");
System.out.println(buf.position());
System.out.println(buf.limit());
System.out.println(buf.capacity());
System.out.println((char)buf.get());
}
}
直接缓冲区与非直接缓冲区:
非直接缓冲区: 通过allocate() 方法分配缓冲区,将缓冲区建立在JVM 的内存中
直接缓冲区:通过allocateDirect() 方法 分配直接缓冲区,将缓冲区建立在物理内存中。可以提高效率
通道: 用于源节点与目标节点的连接。在Java NIO 中负责缓冲区中数据的传输。Channel 本身不存储数据,因此需要配合缓冲区进行传输。
通道的主要实现类
java.nio.channels.Channel 接口:
FileChannel SocketChannel ServerSocketChannel DatagramChannel
获取通道: 1、Java 针对支持通道的类提供了 getChannel() 方法
本地IO : FileInputStream/FileOutputStream RandomAccessFile
网络IO: Socket ServerSocket DatagramSocket
2、 在 JDK 1.7 中的NIO.2 针对各个通道提供了静态方法 open()
在 JDK 1.7 中的NIO.2 的 Files 工具类的 newByteChannel()