浅谈IO和NIO

IO是面向流的(stream),NIO是面向缓冲区的(buffer)。

Java IO面向流意味着每次从流中读一个或多个字节,直至读取所有字节,它们没有被缓存在任何地方。此外,它不能前后移动流中的数据。如果需要前后移动从流中读取的数据,需要先将它缓存到一个缓冲区。 Java NIO的缓冲导向方法略有不同。

在NIO中,使用通道和缓冲区。数据始终从通道读取到缓冲区,或从缓冲区写入通道。数据读取到一个它稍后处理的缓冲区,需要时可在缓冲区中前后移动。这就增加了处理过程中的灵活性。但是,还需要检查是否该缓冲区中包含所有您需要处理的数据。而且,需确保当更多的数据读入缓冲区时,不要覆盖缓冲区里尚未处理的数据。

 

Java IO的各种流是阻塞的。这意味着,当一个线程调用read() 或 write()时,该线程被阻塞,直到有一些数据被读取,或数据完全写入。该线程在此期间不能再干任何事情了。

Java NIO的非阻塞模式,使一个线程从某通道发送请求读取数据,但是它仅能得到目前可用的数据,如果目前没有数据可用时,就什么都不会获取,而不是保持线程阻塞,所以直至数据变的可以读取之前,该线程可以继续做其他的事情。 非阻塞写也是如此。一个线程请求写入一些数据到某通道,但不需要等待它完全写入,这个线程同时可以去做别的事情。 线程通常将非阻塞IO的空闲时间用于在其它通道上执行IO操作,所以一个单独的线程现在可以管理多个输入和输出通道(channel)。

 

NIO的核心,channel, buffer,还有一个selector。这三个构成了NIO的核心。在NIO里面所有的IO都从一个channel开始,channel有点像Stream,但是还是有很多细微的区别的。数据可以从channel读到一个buffer中,也可以从buffer写入到channel里面。

NIO Channel和Streams的区别:1.你可以对Channel进行读和写,但是Stream通常只能读,或者只能写。2.Channel可以读写异步进行。3.Channel总是从Buffer中读数据,或者向Buffer中写数据。

 

NIO和IO各有什么适合的应用场景呢?如果你需要同时处理成千上万的打开的连接,但是每个连接可能只发送一小部分数据,例如一个聊天软件的服务器,NIO会是一个不错的选择;如果你在带宽非常高的情况下,只有数量很小的连接,并且一次发送大量的数据,传统的IO或许更适合。

 

参考:https://www.cnblogs.com/xuehanlee/p/4632518.html

原文地址:https://www.cnblogs.com/stupid-chan/p/9445784.html