读取和写入文件都需要I/O操作调用系统提供的接口,因为磁盘设备是由系统来管理的,我们的应用程序要想访问物理设备只能通过这个方式。但是系统调用都是会涉及到内核空间地址和用户名空间地址的切换问题,原因是操作系统为了保护系统本身的运行安全,从而把内核程序运行使用的内存空间和用户程序运行的内存空间进行隔离造成的。这样做可以保证内核程序的运行安全,但是存在数据从内核空间向用户空间复制的问题。
如果遇到了比较耗时的操作,例如数据从磁盘到内核空间再到用户空间,就会变慢。这时候为了加速I/O访问,内核空间就会使用缓存机制来进行,就是说将从磁盘读出来的文件按照一定的方式进行缓存,如果我们的用户程序访问的是同一段磁盘地址的空间数据,那么直接返回给我们的就是缓存的数据,这样可以减小访问的响应时间。
接下来我们看看有几种文件访问方式吧
标准访问文件的方式
当应用程序调用到read()接口的时候,操作系统先检查内核的高速缓存中有没有需要的数据,如果有直接从缓存中返回,如果没有,则从磁盘中读取,然后存到缓存中。
当应用程序调用write()接口将数据从用户地址空间复制到内核地址空间的缓存中,这时候相对于应用程序来说写操作其实已经完成了,至于什么时候才写到磁盘里面去是由操作系统来决定的,除非是我们调用syns命令。
直接I/O的方式
直接I/O方式就是应用程序直接访问磁盘数据,二部经过操作系统内核数据的缓冲区,这样可以减少一次数据从缓冲区的复制。这种方式一般都是在对数据的缓存管理有应用程序实现的数据库管理系统中。在数据库管理系统中,系统很明确的知道应该缓存那些数据,应该让哪些数据失效,也可以对热点数据预加载,可以加速数据的访问效率。如果是让操作系统进行缓存,则会比较麻烦,因为系统并不知道,哪些是热点数据,哪些数据只需要访问一次就不用了,操作系统只是简单的缓存最近一次从磁盘读取的数据。
但是直接I/O方式也是存在负面的影响,如果我们想要的访问数据不在应用程序的缓存中,那么每次数据都会直接从磁盘进行加载,这种直接加载会非常缓慢。一般直接I/O与异步I/O结合使用会得到比较好的性能。
同步访问文件的方式
这种访问方式其实很好理解,就是读写操作是同步的,与标准访问文件的方式不同的是,只有当数据被成功写到磁盘时才返回给应用成功的标志。这种方式的性能比较差,只有在对一些数据安全性要求较高的场景中才会使用,一般这种操作方式的硬件都是定制的。
异步访问文件方式
异步访问方式是当访问数据的线程发出请求后,线程会接着去处理其他的事情而不是阻塞等待,当接收到请求的数据后继续处理下面操作,这种方式可以明显的提高应用程序的效率,但是事实上访问文件的效率并不会提升。
内存映射的方式
这种方式指的是操作系统将内存中的某一块区域与磁盘中的文件关联起来,当要访问内存中的某一段数据时,转换为访问文件的某一段数据。这样可以减少数据从内核空间缓存到用户空间缓存的数据复制操作,因为两个空间的数据是共享的。
大家好,我是一个程序员,对,就是你们认为的那种程序员,平时会写点文章,一个是可以再这个过程自己也学习并能巩固,第二也是可以跟大家分享一下,各位同是猿类的可以帮忙点关注,点点赞来支持一下你们搬砖路上的小伙伴,谢谢啦。