Skip to content

IO 流简介

  • InputStream/Reader: 所有的输入流的基类,前者是字节输入流,后者是字符输入流。
    • FileInputStream:指定文件读取字节流
    • ObjectInputStream:从输入流中读取 Java 对象(反序列化)
  • OutputStream/Writer: 所有输出流的基类,前者是字节输出流,后者是字符输出流。
    • FileOutputStream:指定文件输出字节流
    • ObjectOutputStream:将对象写入到输出流(序列化),不想被序列化的字段用transient 修饰
  • 不注意的话两者都会出现乱码
    • 如果字符输入流和字符输出流编码不一致,会乱码
    • 字节流是手动转换不当会乱码
  • 字符流主要处理文本,可以简化文本处理流程(不需要手动编解码)
  • 缓冲流:分为字节和字符,给上述的流增加缓冲区,比如每次读取一个字符,直接使用需要每次到磁盘 I/O,但是通过缓冲流包装,可以一次 I/O 缓存,之后去缓存读取,更快。
  • 打印流:PrintStream/PrintWriter ,常用的 System.out.print()就是PrintStream对象的 write 方法
  • 随机访问流:通过文件指针表示下次读写的位置,可以实现大文件的断点续传(分片传输)

I/O模型

  • BIO(Blocking I/O):同步阻塞 I/O,调用 read 后,会一直阻塞,性能较差
  • NIO(Non-blocking I/O):通过 I/O 多路复用模型,避免一直阻塞,先将读取事件注册进复用器,只有不断的轮询看有没有准备好的数据,内核准备好数据,再发起 read 调用
    • 适合高并发,高延迟,如果并发少不一定快,因为需要上下文切换
    • 会通过缓冲区读写,BIO 直接读取
    • Netty 就是基于 NIO 构建的
  • AIO(Asynchronous I/O):和 NIO 类似,不过 AIO 不需要轮询,而是通过回调后被动触发(轮询发现有后主动触发),但是 Linux 下 AIO 支持有限,所以用的少

正在精进