Java IO/NIO学习总结

下面是自己学习整理Java IO/NIO的总结,期间浏览了网上很多优秀的总结分析文章,一并贴在这里供大家学习参考。IO的知识点学习大概分为以下几个部分:

  1. 概念理解

  2. 熟悉Java IO API

  3. 熟悉Java NIO API

  4. 系统的IO优化

  5. 优秀IO/NIO开源框架学习

第一部分:概念理解

什么是IO?IO就是Input(输入)和Output(输出),比如:从文件系统中读取某个文件的内容,一台服务器将数据发送到另一台服务器,这些都是IO操作。IO研究的问题无非就是把什么样的数据(数据格式)以什么数据形式发送到哪里的问题。

第二部分:熟悉Java IO  API

  1. 基于字节操作的 I/O 接口:InputStream 和 OutputStream

  2. 基于字符操作的 I/O 接口:Writer 和 Reader

  3. 基于磁盘操作的 I/O 接口:File(重点)

  4. 基于网络操作的 I/O 接口:Socket(重点)

前两组主要是根据传输数据的数据格式,后两组主要是根据传输数据的方式,虽然 Socket 类并不在 java.io 包下,但是它的实质也是IO。

第三部分:熟悉Java NIO  API

Java NIO的出现是为了弥补IO在很多方面的不足。Java NIO是基于Buffer和Channel的。他们最主要的区别在于:

IO NIO
Stream oriented(面向流) Buffer oriented(面向buffer)
Blocking IO(阻塞) Non blocking IO(非阻塞)
  Selector(选择器)

传统IO操作状态无法记录,不知道读/写了多少,还有多少是有效字节,下次从哪里开始读/写,NIO则很好的解决了这个问题,使得操作更加精确可控,而且读写效率更高。

NIO里关键的Buffer实现:

  • ByteBuffer

  • CharBuffer

  • IntBuffer

  • ShortBuffer

  • LongBuffer

  • FloatBuffer

  • DoubleBuffer

  • MappedbyteBuffer

NIO里关键的Channel实现:

  • FileChannel:从文件中读写数据

  • DatagramChannel:通过UDP 读写网络中的数据

  • SocketChannel:通过TCP读写网络中的数据

  • ServerSocketChannel:可以监听新进来的TCP连接,像web 服务器那样。对每一个新进来得连接都会创建一个SocketChannel。

其它重要的类:

  • Selector

  • SelectionKey

  • Channels

重要概念的理解:同步、异步、阻塞、非阻塞

buffer的理解:capacity、limit、position、mark

第四部分:系统的IO优化

磁盘IO优化:

  • 增加缓存,减少磁盘访问次数

  • 优化磁盘的管理系统,设计最优的磁盘访问策略,以及磁盘的寻址策略,这里是在底层操作系统层面考虑的。

  • 设计合理的磁盘存储数据块,以及访问这些数据块的策略,这里是在应用层面考虑的。如我们可以给存放的数据设计索引,通过寻址索引来加快和减少磁盘的访问,还有可以采用异步和非阻塞的方式加快磁盘的访问效率。

  • 应用合理的 RAID 策略提升磁盘 IO,

网络IO优化:

  • 一个是减少网络交互的次数:要减少网络交互的次数通常我们在需要网络交互的两端会设置缓存,比如 Oracle 的 JDBC 驱动程序,就提供了对查询的 SQL 结果的缓存,在客户端和数据库端都有,可以有效的减少对数据库的访问。关于 Oracle JDBC 的内存管理可以参考《 Oracle JDBC 内存管理》。除了设置缓存还有一个办法是,合并访问请求:如在查询数据库时,我们要查 10 个 id,我可以每次查一个 id,也可以一次查 10 个 id。再比如在访问一个页面时通过会有多个 js 或 css 的文件,我们可以将多个 js 文件合并在一个 HTTP 链接中,每个文件用逗号隔开,然后发送到后端 Web 服务器根据这个 URL 链接,再拆分出各个文件,然后打包再一并发回给前端浏览器。这些都是常用的减少网络 I/O 的办法。

  • 减少网络传输数据量的大小:减少网络数据量的办法通常是将数据压缩后再传输,如 HTTP 请求中,通常 Web 服务器将请求的 Web 页面 gzip 压缩后在传输给浏览器。还有就是通过设计简单的协议,尽量通过读取协议头来获取有用的价值信息。比如在代理程序设计时,有 4 层代理和 7 层代理都是来尽量避免要读取整个通信数据来取得需要的信息。

  • 尽量减少编码:通常在网络 I/O 中数据传输都是以字节形式的,也就是通常要序列化。但是我们发送要传输的数据都是字符形式的,从字符到字节必须编码。但是这个编码过程是比较耗时的,所以在要经过网络 I/O 传输时,尽量直接以字节形式发送。也就是尽量提前将字符转化为字节,或者减少字符到字节的转化过程。

  • 根据应用场景设计合适的交互方式:所谓的交互场景主要包括同步与异步阻塞与非阻塞方式

第五部分:优秀IO/NIO开源框架学习

目前开源社区比较优秀的IO/NIO开源框架有:Apache MINA、Netty

通过学习优秀的开源框架,我们可以升华我们所学,进一步的加深对IO/NIO的理解。以下是一些优秀的参考博客:

1、Java NIO系列教程(重点推荐):

http://www.iteye.com/magazines/132-Java-NIO

2、深入分析 Java I/O 的工作机制(重点推荐):

https://www.ibm.com/developerworks/cn/java/j-lo-javaio/

3、深入分析Java中的中文编码问题(重点推荐):

https://www.ibm.com/developerworks/cn/java/j-lo-chinesecoding/

4、Java深入历险——Java IO

http://www.infoq.com/cn/articles/cf-java-i-o

5、Java NIO分析

https://askingwindy.gitbooks.io/gitbook-java-interview-note/content/io/syn-ays-blocked/nio.html

6、Java NIO原理图文分析

http://weixiaolu.iteye.com/blog/1479656

转载于:https://my.oschina.net/powerisam/blog/645379

你可能感兴趣的:(Java IO/NIO学习总结)