java基础之IO与NIO

来源:互联网 发布:淘宝客服一分钟多少字 编辑:程序博客网 时间:2024/06/06 09:37

      在过去,java在文件或者数据的传输上用的都是IO。但是在如今并发数极高的情况下,IO的效率太低,因为IO是一种阻塞的模式。

      IO是面向流的,其中有原始流和处理流。FileInputStream就是一个原始的字节流,而InputStreamReader便是处理流,对字节进行处理转化为字符。BufferInputReader也是处理流,用于创建一个缓冲区,提高处理的效率。

     我觉得我们程序员在学习的时候一定要想为什么,才能有很大的提高。就像这里,为什么需要缓冲流呢?

     原因:在计算机中,对硬盘的操作效率是远远低于对内存操作的效率的。FileInputStream这个字节流是读一个字节便要读取一次硬盘。假如文件很大,便需要访问很多次硬盘,效率就大大降低。这时候我们会想,如果先把这些字节放在一个地方,然后程序在访问硬盘,将这些数据一次性读取不是能大大提高效率吗。就像下面那样:

 FileInputStream fi = null;          try{              fi = new FileInputStream("/home/gateman/Music/Nickelback - Rockstar.flac");          }catch(FileNotFoundException e){              System.out.println("File not found!");          }            FileOutputStream fo = null;          try{              fo = new FileOutputStream("/home/gateman/tmp/Rockstar.flac");          }catch(Exception e){              System.out.println("error in file output stream's creation");              e.printStackTrace();          }            //bufferStream          BufferedInputStream bis = new BufferedInputStream(fi,512);          BufferedOutputStream bos = new BufferedOutputStream(fo,512);  
从上面红色的代码中可以看出,对缓冲区的大小进行设置,到达设置的大小后进行读取。

我们又会有一个疑问:既然有缓冲区了,效率能大大提高,为什么还需要NIO?

这边涉及到一个知识点:IO是同步阻塞的。一个线程在进行数据的读取的时候,只能持续等待缓冲区的数据被填满,不能做其他事情。

而NIO是同步非阻塞的(有些地方说是异步非阻塞的,但是那是AIO了,不是NIO)。这个为什么好呢?

必须说道NIO是面向缓冲区的,从读取进行讲解。线程读取文件过程:通道注册到selector ,一旦通道内有数据进来,selector就会收到消息,这就是典型的观察者模式,即异步。接着selector知道了是哪个通道有了数据,将数据放到缓冲区中,然后再从缓冲区中读取数据。为什么说NIO是同步非阻塞的呢?因为NIO在等待的过程中可以做其他事,但是必须去检查buffer中是否存在数据。
 详情见

javaNIO系列教程  

java缓冲流简介 

javaNIO是同步还是异步