(一)访问文件的方式
读取和写入文件I/O操作都调用操作系统提供的接口,因为磁盘设备是由操作系统管理的,应用程序要访问物理设备只能通过系统调用的方式来工作,但是系统将内存空间分成了内核空间地址和用户空间地址,所有在读取文件或写入文件时也必然存在数据可能需要从内核空间向用户空间复制的问题。
1.标准访问文件的方式:
(1)读取:应用程序调用read()接口,操作下同检查在内核的高速缓存中有没有存在需要的数据,有的话直接拿,没有的话从磁盘中读取,然后缓存在操作系统的缓存中。
(2)写出:应用程序调用write()接口,将数据从用户地址空间复制到内核地址空间的缓存中。这时对用户来说写操作已经完成,至于什么时候再写到磁盘中由操作系统决定,或者调用sync(此方法在java.io.FileDescriptor中)同步命令。
2.直接I/O方式:
所谓的直接I/O就是应用程序直接访问磁盘数据,不经过操作系统的内核缓存区,这样就避免了内核空间到用户空间的复制操作。这种访问文件的方式通常是在对数据的缓存管理由应用程序实现的数据库管理系统中。如在数据库管理系统中,系统知道哪些数据需要缓存,应该失效哪些数据,哪些数据是热点数据,可以提前加载,这样可以提高访问效率。因为操作系统是缓存最近一次从磁盘读取的数据,而且操作系统并不知道哪些数据是热点数据,需要提前加载,所以在这种情况下是不管用的。
但是直接I/O也有缺点,如果在缓存中找不到想要的数据,那就得直接从磁盘中读取,而这种直接读取的速度非常慢。通常直接I/O跟异步I/O结合使用的话性能会更好。
3.同步访问文件的方式:
同步访问文件的方式跟标准访问文件方式相同,但是同步访问文件只有当文件成功 写到磁盘时才会返回成功标记,这种访问方式效率低,只有当一些数据安全性要求比较高的场所中才会使用,而且通常这种操作方式的硬件都是定制的。
4.异步访问文件的方式:
异步访问文件的方式就是访问数据的线程发出请求之后,线程会去先处理其他的事情,而不是阻塞等待,当请求的数据返回后继续处理下面的操作。这种访问文件的方式可以明显提高应用程序的效率,但不会改变访问程序的效率。
5.内存映射的方式:
内存映射的方式是指操作系统将内存中的某一区域与磁盘中的文件关联起来,当要访问内存中的一段数据时,转换为访问文件的某一段数据。这种方式的目的同样是减少数据从内核空间缓存到用户空间缓存的数据复制操作,因为这两个空间的数据是共享的。