Java IO流

吃可爱长大的小学妹 提交于 2019-11-26 16:46:30

一、BIO(同步、阻塞)

1、概述

IO流简单来说就是input和output流,IO流主要是用来处理设备之间的数据传输,Java IO对于数据的操作都是通过流实现的,而java用于操作流的对象都在IO包中。

2、分类

按操作数据分为:字节流(Reader、Writer)和字符流(InputStream、OutputStream)

按流向分:输入流(Reader、InputStream)和输出流(Writer、OutputStream)


3、字符流

概述

只用来处理文本数据

数据最常见的表现形式是文件,字符流用来操作文件的子类一般是FileReader和FileWriter

字符流读写文件注意事项:

  • 写入文件必须要用flush()刷新
  • 用完流记得要关闭流
  • 使用流对象要抛出IO异常
  • 定义文件路径时,可以用"/"或者"\"
  • 在创建一个文件时,如果目录下有同名文件将被覆盖
  • 在读取文件时,必须保证该文件已存在,否则抛出异常

字符流的缓冲区

  • 缓冲区的出现是为了提高流的操作效率而出现的
  • 需要被提高效率的流作为参数传递给缓冲区的构造函数
  • 在缓冲区中封装了一个数组,存入数据后一次取出

4、字节流

概述

用来处理媒体数据

字节流读写文件注意事项:

  • 字节流和字符流的基本操作是相同的,但是想要操作媒体流就需要用到字节流
  • 字节流因为操作的是字节,所以可以用来操作媒体文件(媒体文件也是以字节存储的)
  • 输入流(InputStream)、输出流(OutputStream)
  • 字节流操作可以不用刷新流操作
  • InputStream特有方法:int available()(返回文件中的字节个数)

字节流的缓冲区

  • 字节流缓冲区跟字符流缓冲区一样,也是为了提高效率

5、Java Scanner类

Java 5添加了java.util.Scanner类,这是一个用于扫描输入文本的新的实用程序

关于nextInt()、next()、nextLine()的理解

nextInt():只能读取数值,若是格式不对,会抛出java.util.InputMismatchException异常

next():遇见第一个有效字符(非空格,非换行符)时,开始扫描,当遇见第一个分隔符或结束符(空格或换行符)时,结束扫描,获取扫描到的内容

nextLine():可以扫描到一行内容并作为字符串而被捕获到

关于hasNext()、hasNextLine()、hasNextxxx()的理解

就是为了判断输入行中是否还存在xxx的意思

 

 

二、NIO(同步、非阻塞)

NIO之所以是同步,是因为它的accept/read/write方法的内核I/O操作都会阻塞当前线程

 

首先,我们要先了解一下NIO的三个主要组成部分:Channel(通道)、Buffer(缓冲区)、Selector(选择器)

(1)Channel(通道)

Channel(通道):Channel是一个对象,可以通过它读取和写入数据。可以把它看做是IO中的流,不同的是:

  • Channel是双向的,既可以读又可以写,而流是单向的
  • Channel可以进行异步的读写
  • 对Channel的读写必须通过buffer对象

正如上面提到的,所有数据都通过Buffer对象处理,所以,您永远不会将字节直接写入到Channel中,相反,您是将数据写入到Buffer中;同样,您也不会从Channel中读取字节,而是将数据从Channel读入Buffer,再从Buffer获取这个字节。

因为Channel是双向的,所以Channel可以比流更好地反映出底层操作系统的真实情况。特别是在Unix模型中,底层操作系统通常都是双向的。

在Java NIO中的Channel主要有如下几种类型:

  • FileChannel:从文件读取数据的
  • DatagramChannel:读写UDP网络协议数据
  • SocketChannel:读写TCP网络协议数据
  • ServerSocketChannel:可以监听TCP连接

(2)Buffer

Buffer是一个对象,它包含一些要写入或者读到Stream对象的。应用程序不能直接对 Channel 进行读写操作,而必须通过 Buffer 来进行,即 Channel 是通过 Buffer 来读写数据的。

在NIO中,所有的数据都是用Buffer处理的,它是NIO读写数据的中转池。Buffer实质上是一个数组,通常是一个字节数据,但也可以是其他类型的数组。但一个缓冲区不仅仅是一个数组,重要的是它提供了对数据的结构化访问,而且还可以跟踪系统的读写进程。

(三)Selector(选择器对象)

首先需要了解一件事情就是线程上下文切换开销会在高并发时变得很明显,这是同步阻塞方式的低扩展性劣势。

Selector是一个对象,它可以注册到很多个Channel上,监听各个Channel上发生的事件,并且能够根据事件情况决定Channel读写。这样,通过一个线程管理多个Channel,就可以处理大量网络连接了。

selector优点

有了Selector,我们就可以利用一个线程来处理所有的channels。线程之间的切换对操作系统来说代价是很高的,并且每个线程也会占用一定的系统资源。所以,对系统来说使用的线程越少越好。

 

三、AIO(异步、非阻塞)

 

AIO是异步IO的缩写,虽然NIO在网络操作中,提供了非阻塞的方法,但是NIO的IO行为还是同步的。对于NIO来说,我们的业务线程是在IO操作准备好时,得到通知,接着就由这个线程自行进行IO操作,IO操作本身是同步的。

但是对AIO来说,则更加进了一步,它不是在IO准备好时再通知线程,而是在IO操作已经完成后,再给线程发出通知。因此AIO是不会阻塞的,此时我们的业务逻辑将变成一个回调函数,等待IO操作完成后,由系统自动触发。

与NIO不同,当进行读写操作时,只须直接调用API的read或write方法即可。这两种方法均为异步的,对于读操作而言,当有流可读取时,操作系统会将可读的流传入read方法的缓冲区,并通知应用程序;对于写操作而言,当操作系统将write方法传递的流写入完毕时,操作系统主动通知应用程序。 

原文转自:https://www.cnblogs.com/sxkgeek/p/9488703.html 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!