《JAVA NIO》读书笔记+java.nio源码解析

来源:互联网 发布:js获取跳转前的url 编辑:程序博客网 时间:2024/05/18 07:14

java.io之后,为什么还要有java.nio?

在大多数情况下,java应用程序并非真的受着I/O的束缚。操作系统并非不能快速传送数据,让java有事可做。相反,是JVM自身在I/O方面欠佳。操作系统与java基于流的I/O模型有些不匹配。操作系统要移动的是大块数据(缓冲区),这往往是在硬件直接存储器存取(DMA)的协助下完成的。而JVM的I/O类喜欢操作小块数据--单个字节、几行文本。结果,操作系统送来整缓冲区的数据,java.io的流数据类再花大量时间把它们拆成小块,往往拷贝一个小块数据就要往返于几个对象。操作系统喜欢整卡车的运来数据,java.io类则喜欢一铲子一铲子的加工数据。有了NIO,就可以轻松的把一卡车数据备份到直接使用的地方(byteBuffer对象)。

这并不是说使用传统的I/O模型无法移动大量数据----当然可以,现在依然可以。具体的说,RandomAccessFile类在这方面的效率就不低,只要坚持使用基于数组的read()和

write()方法。这些方法与底层操作系统调用相当接近,尽管必须保留至少一份缓冲区拷贝。

不过,如果代码的大部分时间都处于I/O等待状态,那么,该考虑一下提升I/O效率的问题了,否则,精心打造的代码多数时间都得闲着。

java.nio之Buffer

一个buffer对象是固定数量的数据的容器,其作用是一个存储器,或者分段运输区,在这里数据可被存储并在之后用于检索。

上图是buffer的类层次图。顶部是通用的Buffer类。

接下来,看一下Buffer类的源码。

package java.nio;public abstract class Buffer {// Buffer类的四个属性 mark <= position <= limit <= capacity// 标记。一个备忘位置private int mark = -1;// 位置。下一个要被读或写的元素的索引。位置会自动由相应的get()和put()函数更新。private int position = 0;// 上界。缓冲区的第一个不能被读或写的元素。或者说,缓冲区中现存元素的计数。private int limit;// 容量。缓冲区能够容纳的数据元素的最大数量。这一容量在缓冲区创建时被设定,并且永远不能改变。private int capacity;//构造方法Buffer(int mark, int position, int limit, int capacity) {if (capacity < 0) {throw new IllegalArgumentException("negative capacity :" + capacity);}this.capacity = capacity;limit(limit);position(position);if (mark > 0) {if (mark > position) {throw new IllegalArgumentException("mark不能大于positon");}this.mark = mark;}}public final Buffer limit(int limit) {if (limit > capacity || limit < 0) {throw new IllegalArgumentException("limit不能大于capacity,不能小于0");}this.limit = limit;if (position > limit) {position = limit;}if (mark > limit) {mark = -1;}return this;}public final Buffer position(int position) {if (position > limit || position < 0) {throw new IllegalArgumentException("position不能大于limit,不能小于0");}this.position = position;if (mark > position) {mark = -1;}return this;}}






0 0