BufferedInputStream->FilterInputStream->InputStream
这些类的核心read函数最后都是调用InputStream里面的read函数,一个byte一个byte的读取(int->byte),效率不高
public int read(byte b[], int off, int len) throws IOException { if (b == null) { throw new NullPointerException(); } else if (off < 0 || len < 0 || len > b.length - off) { throw new IndexOutOfBoundsException(); } else if (len == 0) { return 0; } int c = read(); if (c == -1) { return -1; } b[off] = (byte)c; int i = 1; try { for (; i < len ; i++) { c = read(); if (c == -1) { break; } b[off + i] = (byte)c; } } catch (IOException ee) { } return i; }
FileInputStream(FileChannel(NIO))->InputStream
上面的BufferedInputStream读取太慢,FileInputStream引入了NIO中的FileChannel(rt.jar java.nio.channels)提供了缓冲区,提升了InputStream的读取效率
Java NIO有三大核心部件:java
缓冲区
IO操做通道,能够操做设备、文件、网络套接字或程序组件
多路复用选择器
通道(Channel)和缓冲区(Buffer)。通道表示打开到 IO 目标的链接。若须要使用 NIO 系统,须要获取用于链接 IO 目标的通道以及用于容纳数据的缓冲区。而后操做缓冲区,对数据进行处理
缓冲区(Buffer):缓冲区是一个线性有限的用来存放从NIO Channel中读取出得数据的区域
Buffer就是一个数组,用来存放一些特定的数据类型的元素,每种数据类型都有一个对应的缓冲区(除了boolean类型),他们都是Buffer类的子类,其中包括:数组
allocate (int capacity) 是用来分配capacity大小空间返回缓冲区对象的函数
public final Buffer mark() { mark = position; return this; } public final Buffer reset() { int m = mark; if (m < 0) throw new InvalidMarkException(); position = m; return this; }
mark、position、limit、capcity之间的关系:mark <= position <= limit <= capacity
网络
get:获取 Buffer 中的数据框架
put:放入数据到 Buffer 中函数
new byte[capacity]
allocateDirect(int)
工厂方法建立直接字节缓冲区。此方法返回的缓冲区一般比非直接缓冲区具备更高的分配和释放成本。直接缓冲区的内容可能位于正常垃圾收集堆以外,所以它们对应用程序内存占用的影响可能不明显。所以,建议将直接缓冲区主要分配给受底层系统本机I/O操做影响的大型、长寿命缓冲区。通常来讲,只有当直接缓冲区在程序性能上产生可测量的增益时,才分配直接缓冲区isDirect
方法能够判断该缓冲区是否是直接缓冲区未完待续:一篇文章讲不完Java NIO,Channel和Selector将在下一篇文章中进行介绍性能