JavaSE知识点总结:IO和NIO

本文深入探讨Java的IO和NIO系统,包括标准阻塞IO和非阻塞IO的概念,详细介绍了字节流、字符流、文件流、数组流、管道流、数据流、缓冲流、转换流、打印流和对象流。此外,还讲解了NIO中的Buffer、Channel和Selector机制,以及标准NIO的步骤。

IO和NIO

Java BIO java blocking IO 阻塞式IO
Java NIO java non-blocking IO 非阻塞IO

标准阻塞IO

字节流:以 8 位(即 1 byte,8 bit)作为一个数据单元,数据流中最小的数据单元是字节。

字符流:以 16 位(即 1 char,2 byte,16 bit)作为一个数据单元,数据流中最小的数据单元是字符, Java 中的字符是 Unicode 编码,一个字符占用两个字节。 IO最基本的是 4
个抽象类:InputStream、OutputStream、Reader、Writer。最基本的方法也就是一个读 read() 方法、一个写
write() 方法。

文件流(File):从磁盘文件中输入输出或读写数据

  • FileInputStream、FileOutputStream
  • FileReader、FileWriter

数组流(byte[]、char[]): 从数组中输入输出或读写数据

  • ByteArrayInputStream、ByteArrayOutputStream
  • CharArrayReader、CharArrayWriter

管道流:从线程共用的管道中读写数据。

  • PipedInputStream、PipedOutputStream
  • PipedReader、PipedWriter

数据流:将基础类型数据以流的形式输入文件、输出到程序

  • DataInputStream、DataOutputStream

缓冲流:二次处理包装流,在给普通流增加缓冲功能

  • BufferedInputStream、BufferedOutputStream
  • BufferedReader、BufferedWriter

转换流:二次处理包装流,字节流和字符流相互转换

  • InputStreamReader、OutputStreWriter

打印流:控制台的输入输出 System.io 和 System.out

  • PrintStream、PrintWriter

对象流:主要用于对象序列化和反序列化

  • ObjectInputStream、ObjectOutputStream

非阻塞新IO

Buffer(缓冲)

  • Buffer是一个对象,它用来存放即将发送的数据和即将到来的数据。Buffer实际上就是一个数组,通常是字节数组,但是这个数组提供了访问数据的读写等操作属性,如位置,容量,上限等概念。
  • 在NIO中,Buffer是一个抽象类,常用的子类有、对于文件读写的:ByteBuffer、IntBuffer、ShortBuffer、CharBuffer、LongBuffer、DoubleBuffer、FloatBuffer、ShortBuffer。对于网络读写来说,用的最多的是ByteBuffer。

向Buffer中读写数据有两种方式:

从Channel读写到Buffer
****int bytesWritten = inChannel.write(buf);
****int bytesRead = inChannel.read(buf);
从Buffer中读写数据的两种方式:
****:使用get()方法从Buffer中读取数据。如:byte aByte = buf.get();
****:通Buffer的put()方法写到Buffer里。如:buf.put(127); 

Channel (通道)

  • 与Stream(流)的不同之处在于通道是双向的,流只能在一个方向上操作,而通道可以用于读,写或者二者同时进行,最关键的是可以和多路复用器结合起来,提供状态位,多路复用器可识别Channel所处的状态。
  • 通道可以分两大类:
    用于网络读写的SelectableChannel,和用于文件操作的FileChannel。具体来说:通过FileChannel可以从文件读或者向文件写入数据;通过SocketChannel,以TCP来向网络连接的两端读写数据;通过ServerSocketChanel能够监听客户端发起的TCP连接,并为每个TCP连接创建一个新的SocketChannel来进行数据读写;通过DatagramChannel,以UDP协议来向网络连接的两端读写数据。

Selector(选择器)

  • Selector提供选择已经就绪的任务的能力。简单说,就是Selector会不断轮询注册在Selector上的通道(Channel),如果这个通道发生了读写操作,这个通道就会处于就绪状态,会被Selector察觉到,然后通过SelectionKey可以取出就绪的Channel集合,从而进行IO操作。
  • 一个Selector可以负责成千上万的通道,没有上限。这也是JDK使用了epoll代替传统的Select实现,获得连接句柄没有限制。意味着我们只需要一个线程负责Selector的轮询,就可以接入成百上千的客户端,这是JDK NIO库的巨大进步。
  • Selector类是NIO的核心类,Selector能够检测多个注册的通道上是否有事件发生,如果有事件发生,便获取事件然后针对每个事件进行相应的响应处理。这样一来,只是用一个单线程就可以管理多个通道,也就是管理多个连接。这样使得只有在连接真正有读写事件发生时,才会调用函数来进行读写,就大大地减少了系统开销,并且不必为每个连接都创建一个线程,不用去维护多个线程,并且避免了多线程之间的上下文切换导致的开销。
  • 与Selector有关的一个关键类是SelectionKey,一个SelectionKey表示一个到达的事件,这2个类构成了服务端处理业务的关键逻辑。

标准的NIO步骤
一个简单(标准)的NIO输入输出一般包含如下步骤:

  1. 从数据源获取通道 ;
  2. 分配缓冲区 ;
  3. 切换缓存区为写模式;
  4. 从通道读取数据写入缓冲区;
  5. 切换缓冲区为读模式 ;
  6. 缓冲区数据写入通道中 ;
  7. 关闭资源;
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值