磁盘IO的访问方式

缓存IO(标准IO)

数据先从磁盘复制到内核空间的缓冲区,然后从内核空间缓冲区复制到应用程序的地址空间

读操作

  1. 操作系统检查内核的缓冲区有没有需要的数据,如果已经缓存了,那么就直接从缓存中返回

  2. 否则从磁盘中读取,然后缓存在操作系统的内核缓存中

写操作

  1. 将数据从用户空间复制到内核空间缓存中

  2. 至于什么时候再写到磁盘中由操作系统决定

    • 例外:本地显示调用了sync同步命令

优缺点

优点

在一定程度上分离了内核空间和用户空间,保护系统本身的运行安全,减少读取磁盘的次数,从而提高性能

缺点

应用程序地址空间和缓存之间进行了多次数据拷贝操作,造成开销大

直接IO

应用程序直接访问磁盘数据,不经过内核缓冲区

  • 直接加载速度非常缓慢

内存映射

将硬盘上文件的位置与进程逻辑地址空间中一块大小相同的区域一一对应,当要访问内存中一段数据时,可根据这个逻辑地址空间映射到实际文件中进行操作,从而不必执行IO操作。

说白了就是使用虚拟内存将磁盘的文件数据加载到虚拟内存的内存页,然后就可以直接操作内存页数据。

  • 适用于大量数据的传输
  • 内存映射处理文件时,不再执行IO操作

内存映射

创建内存映射的文件

RandomAccessFile raf = new RandomAccessFile("test.txt", "rw";);
FileChannel fc = raf.getChannel();
//将test.txt文件所有数据映射到虚拟内存,只读
MappedByteBuffer mbuff = fc.map(MapMode.READ_ONLY, 0, fc.size());

参考资料

  1. 内存映射