您的位置:首页 > 编程语言 > Java开发

读书笔记-《Java NIO》:第三章 通道(4)

2017-09-25 23:00 253 查看
1. 内存映射文件

FileChannel中有一个map()方法,这个方法是做什么用的呢?



记不记得第一章讲过的虚拟内存和直接存储的概念?不记得没关系,看下面这张图。常规情况下,用户空间的进程想要读取一块磁盘数据,需要发起系统调用read(),read()是系统内核,read()读取数据后,放入内核空间的缓冲区,再由内核缓冲区重新组装到用户空间的缓冲区,同一份数据要在内核区间和用户空间保存两份。是不是很浪费?第一章讲了直接存储的概念读书笔记-《Java
NIO》 : 第一章 简介,内核的缓冲区可以通过DMA直接存储技术,读写磁盘数据,内核空间和用户空间又可以通过虚拟内存技术 共用一块缓冲区,像下面这样。这样就节省了内存,提高了读写速度。



这块由用户进程和内核共享的内存空间的映射就是MappedByteBuffer,用户可以通过MappedByteBuffer来访问和使用这块空间。

我们来看一下map()函数的返回值,正是MappedByteBuffer,也就是说map()返回一个这样的共享内存区块。

通过这种机制访问一个文件比使用常规方法要高效很多,因为它不需要做明确的系统调用(一般都很耗时),而且访问的这段内存空间是系统的内核空间缓存,不消耗Java虚拟机的内存堆。

来看下MappedByteBuffer中的几个方法。



当我们为一个文件建立虚拟内存映射之后,文件数据大多数情况下,不会从磁盘中填充到内存(这取决于操作系统)。对于映射缓冲区,虚拟内存系统将根据你的需要将文件中相应的区块数据读进来。

load()方法是做什么的呢?

load()方法会将整个文件加载到内存,使它常驻内存,这样你访问这个文件,相当于直接和内存打交道,延迟最小。

isLoaded()方法就是判断一个被映射的文件是否完全常驻内存了。

force()方法是强制将映射区上的更改应用到磁盘存储器上。    

2. Channel-to-Channel传输

有一种场景我们经常遇到,就是将一个文件由一个位置传输到另一个位置,FileChannel添加了一些优化方法来提高传输的效率。



transferFrom()和transferTo()方法允许将一个通道交叉连接到另一个通道而不需要通过一个中间的缓冲区来传输数据。只有FileChannel类有这两个方法,其他的Channel没有。

今天就到这儿,明天继续( ^_^ )





内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  nio