Java NIO简介
前面介绍的是传统的io,在java.io包下。传统的io有一下缺点:
- 传统的io是bio(阻塞式的io),使用read()系列方法读取数据时,如果没有可读取的数据,会一直阻塞该线程,读取到数据后,线程才继续往下执行。
- 不管是字节流还是字符流,底层都是基于字节实现的,如果不使用缓冲区,会一个字节一个字节地处理,效率极低。
- 读文件时需要从内核空间复制数据到用户空间,写文件时需要把数据从用户空间传递到内核空间,很花时间。
java不具备直接操作硬件的能力,不能直接操作计算机硬件。os是由c/c++写的,代码执行效率极高,操作硬件能力强。
当java程序要使用计算机硬件时,比如要使用摄像头,要读写磁盘文件等,是由jvm向os发出请求,由os来操作硬件。
计算机内存大体可分为2部分:
- 内核空间,运行os自带的程序,比如说windows启动程序、资源管理器、注册表等。
- 用户空间,运行用户程序,比如说qq、酷狗、idea等。
这样做的好处是,将系统内核和用户程序分开,即便用户程序出了问题,也不会影响到系统内核,系统内核更加安全。
但也造成了一个问题:用户程序不能直接访问内核空间的数据。
读文件:jvm向os发出请求 -> os把磁盘文件中存储的数据读取到内核空间 -> os再把这些数据从内核空间复制到用户空间 -> jvm使用用户空间的这些数据。
写文件:jvm向os发出请求 -> os把要写的数据从用户空间复制到内核空间 -> os把这些数据从内核空间写到磁盘文件。
jvm是运行在用户空间的一个程序。不能直接访问内核空间的数据。传统的io进行磁盘文件读写要把数据从内核空间复制到用户空间,或者把数据从用户空间复制到内核空间,会花费大量的时间,尤其是读写的数据量较大时,速度很慢。
从jdk1.4开始,java提供了一系列改进的新io,称为nio(new io)。新增的io在java.nio包中,同时也改写了java.io包中的很多类。
nio可以将内核空间中的文件数据映射到用户空间,不必复制,节省了时间,效率更高。
我们常说nio是把磁盘文件映射到内存中,从而直接对磁盘文件进行读写,这其实是不准确的,java不能直接操作硬件,需要借助os。
nio中的主要类:
- channel 可以将内核空间中的文件数据映射到用户空间
- buffer 缓冲区,批量读写数据
- charset 字符集,用于字符序列的编码、解码
- selector 提供非阻塞式的io
上一篇: jQuery,js如何扩展自定义方法