转载自:李会军•宁静致远java
在上一篇文章中介绍了缓冲区内部对于状态变化的跟踪机制,而对于NIO中缓冲区来讲,还有不少的内容值的学习,如缓冲区的分片与数据共享,只读缓冲区等。在本文中咱们来看一下缓冲区一些更细节的内容。数组
缓冲区的分配app
在前面的几个例子中,咱们已经看过了,在建立一个缓冲区对象时,会调用静态方法allocate()来指定缓冲区的容量,其实调用 allocate()至关于建立了一个指定大小的数组,并把它包装为缓冲区对象。或者咱们也能够直接将一个现有的数组,包装为缓冲区对象,以下示例代码所示:dom
[java] view plain copypost
缓冲区分片spa
在NIO中,除了能够分配或者包装一个缓冲区对象外,还能够根据现有的缓冲区对象来建立一个子缓冲区,即在现有缓冲区上切出一片来做为一个新的缓冲区,但现有的缓冲区与建立的子缓冲区在底层数组层面上是数据共享的,也就是说,子缓冲区至关因而现有缓冲区的一个视图窗口。调用slice()方法能够建立一个子缓冲区,让咱们经过例子来看一下:操作系统
[java] view plain copy.net
在该示例中,分配了一个容量大小为10的缓冲区,并在其中放入了数据0-9,而在该缓冲区基础之上又建立了一个子缓冲区,并改变子缓冲区中的内容,从最后输出的结果来看,只有子缓冲区“可见的”那部分数据发生了变化,而且说明子缓冲区与原缓冲区是数据共享的,输出结果以下所示:
只读缓冲区
只读缓冲区很是简单,能够读取它们,可是不能向它们写入数据。能够经过调用缓冲区的asReadOnlyBuffer()方法,将任何常规缓冲区转 换为只读缓冲区,这个方法返回一个与原缓冲区彻底相同的缓冲区,并与原缓冲区共享数据,只不过它是只读的。若是原缓冲区的内容发生了变化,只读缓冲区的内容也随之发生变化:
[java] view plain copy
若是尝试修改只读缓冲区的内容,则会报ReadOnlyBufferException异常。只读缓冲区对于保护数据颇有用。在将缓冲区传递给某个 对象的方法时,没法知道这个方法是否会修改缓冲区中的数据。建立一个只读的缓冲区能够保证该缓冲区不会被修改。只能够把常规缓冲区转换为只读缓冲区,而不能将只读的缓冲区转换为可写的缓冲区。
直接缓冲区
直接缓冲区是为加快I/O速度,使用一种特殊方式为其分配内存的缓冲区,JDK文档中的描述为:给定一个直接字节缓冲区,Java虚拟机将尽最大努 力直接对它执行本机I/O操做。也就是说,它会在每一次调用底层操做系统的本机I/O操做以前(或以后),尝试避免将缓冲区的内容拷贝到一个中间缓冲区中 或者从一个中间缓冲区中拷贝数据。要分配直接缓冲区,须要调用allocateDirect()方法,而不是allocate()方法,使用方式与普通缓冲区并没有区别,以下面的拷贝文件示例:
[java] view plain copy
内存映射文件I/O
内存映射文件I/O是一种读和写文件数据的方法,它能够比常规的基于流或者基于通道的I/O快的多。内存映射文件I/O是经过使文件中的数据出现为 内存数组的内容来完成的,这其初听起来彷佛不过就是将整个文件读到内存中,可是事实上并非这样。通常来讲,只有文件中实际读取或者写入的部分才会映射到内存中。以下面的示例代码:
[java] view plain copy
关于缓冲区的细节内容,咱们已经用了两篇文章来介绍。在下一篇中将会介绍NIO中更有趣的部分Nonblocking I/O。
(未完待续)