Java IO 知识点总结

IO的分类

  • 按照流的流向分,可以分为输⼊流和输出流;
  • 按照操作单元划分,可以划分为字节流和字符流;
  • 按照流的⻆⾊划分为节点流和处理流。

Java IO类很多,主要是由以下四个抽象基类派生出来的:

  • InputStream/Reader: 所有的输⼊流的基类,前者是字节输⼊流,后者是字符输⼊流。
  • OutputStream/Writer: 所有输出流的基类,前者是字节输出流,后者是字符输出流。

为什么需要分字节流和字符流?
在数据传输和存储的时候,基本都是以字节为最小存储单元,所以,需要使用到字节流;给人们阅读的文字字符之类的信息,需要将字节转化为字符,转化的工作就是由JVM承担的,开销很大,所以,直接提供一个字符流用于操作字符,这样就可以节省开销。如果是音频和图片等文件,用字节流,如果是文本之类的,用字符流。

依据同步和阻塞

  • BIO:同步阻塞,数据的读写必须阻塞在一个线程内等待完成。
  • NIO:同步非阻塞,数据读写是非阻塞的,意思是读写线程不需要等待数据,而是可以读写数据的时候再进行IO,写但是IO行为还是同步的,需要一个线程保持在线完成读写。
  • AIO:异步非阻塞,不需要阻塞等待IO响应,也不需要同步接收数据,相当于后台帮忙将数组放在一个缓冲区,等数据接收完毕了,在通过回调机制去处理。

IO的使用场景

根据文件类型:

  • 如果是音频和图片等文件,用字节流。
  • 如果是文本之类的,用字符流。

根据阻塞同步类型:

  • 活动连接数不高,小于单机1000,连接的数据量大,就可以采用BIO,这样让每个线程专注于自己的线程,不需要过多考虑系统的过载和限流的问题。
  • 十万百万级的连接的时候,可以采用NIO或者AIO。

NIO实现原理

NIO中存在三个重要的组件,分别是Buffer、Channel和Selector,Buffer主要用来缓存不同类型数据,Channel负责具体的IO连接操作,Selector负责监听多个通道的事件。

工作原理是这样的,IO的连接由通道负责,然后IO的数据都会先存到通道对应的一个缓存区中,选择器由一个线程进行运行,不断监听每个通道的时间,通道中的IO是可读或者可写状态时,就会被记录在选择器上。当服务端调用选择器的时候,就可以知道有没有可用的IO的时间,然后再调度线程去同步处理IO。

原来是每个线程分别等待一个对应的IO事件,这样造成阻塞,而NIO本质是通过一个线程去轮询IO是否可用,然后构成一个可操作的IO的缓冲队列,最后利用有限的线程去处理缓冲队列上的IO连接,这样可以避免没有IO都需要一个线程进行阻塞等待。
参考博客

原文地址:https://www.cnblogs.com/lippon/p/14141152.html