Migarated from here at ‘2012-05-22 17:35:03’.
java.nio与java.io的根本区别是:java.io操作是基于byte的stream方式(基于字节的“流”方式);而java.nio是基于buffer的block方式(基于“缓冲区”的“块”方式)。之所以做出这样的改变,是为了更好地利用OS的IO操作调用,以显著地提高IO的工作效率。但是代价是java.nio的使用会失去一些java.io的简单性和优雅性。
java.nio的核心概念是Channel和Buffer,所有的IO操作都由Channel经由Buffer实现。
在JDK1.4引入java.nio时,java.io的代码就使用java.nio重新实现了,并加入了相应的java.nio概念,如Channel。
在Buffer内部,注意Position, Limit, Capacity三个概念。
Buffer.flip()方法的实质是做了两件事情,以完成buffer读写操作的状态切换:
1. 它将limit 设置为当前position。
2. 它将position 设置为0。
- 类似的,Buffer.clear()做了这样两件事:
1. 它将limit 设置为与capacity相同。
2. 它设置position 为0。
Buffer.get(…)和buffer.put(…)是对Buffer进行读写操作的方法。
下面的内部循环概括了使用缓冲区将数据从输入通道拷贝到输出通道的典型过程。
1 | while (true) { |
read() 和 write() 调用得到了极大的简化,因为许多工作细节都由缓冲区完成了。clear() 和flip()方法用于让缓冲区在读和写之间切换。
更高级的Buffer使用包括:缓冲区分片(联想到了DB记录存储方式的“槽”,不知道有没有关系),只读缓冲区,直接缓冲区,内存映射文件IO(直接修改内存某区域就意味着修改磁盘上的文件,使用OS的调用速度会更快,但程序员应该保证使用过程的正确无误),将文件映射到内存。
分散和聚集:分散/聚集 I/O是使用多个而不是单个缓冲区来保存数据的读写方法。对于将数据流划分为单独的部分很有用,这有助于实现复杂的数据格式。在分散读取中,通道依次填充每个缓冲区。填满一个缓冲区后,它就开始填充下一个。在某种意义上,缓冲区数组就像一个大缓冲区。
文件锁定。文件锁定可能是一个复杂的操作,特别是考虑到不同的操作系统是以不同的方式实现锁这一事实。下面的指导原则将帮助您尽可能保持代码的可移植性:只使用排它锁。将所有的锁视为劝告式的(advisory)。