https://www.bilibili.com/video/BV1ct411n7oG?p=173
https://www.sxt.cn/Java_jQuery_in_action/ten-javaio-streamclass.html
目录
流的分类
字节流和字符流(从处理数据的角度分)
按照处理数据的角度分类,可以分为字节流和字符流。
能使用字符流的地方,全部都可以使用字节流;
但能使用字节流,不一定能使用字符流(比如音频文件)。
输入流和输出流(从流向的角度分)
从流向的角度分类,可分为输入流(Reader、InputStream)和输出流(OutputStream、Writer)。
节点流和处理流(从功能的角度分)
按照功能的角度分类,可以分为节点流和处理流。
始终处于第一线的流,称为节点流。
在节点流的基础上,为了提升性能,对其进行装饰、包装,那这个流称为处理流。
若没有节点流,则处理流发挥不了任何的作用。
一般看到File、ByteArray这样的名字,是节点流,比如FileInputStream、ByteArrayInputStream。
其他的可以理解为操作方便、提升性能的处理流,比如BufferedInputStream(缓冲流)、DataInputStream(为了处理数据方便的流)、ObjectInputStream。
四个抽象类
InputStream和OutputStream的数据单位为字节。
Reader和Writer的数据单位为字符。
一切东西都可以把它还原为字节,但不是所有的东西都能还原为字符(比如图片、音频、视频、word、excel等)。
InputStream
InputStream是输入流。
他实现了关闭的接口Closeable:
public abstract class InputStream implements Closeable {......}
Closeable不是释放用到的资源的,
注意,Java虚拟机是无权调用垃圾回收机制的,只能去通知。
Closeable是通知操作系统(OS),这里的资源可以释放了。不是Closeable去释放,是操作系统来释放。
InputStream抽象类有一个close方法,是关闭此输入流并释放与流相关联的任何系统资源。(注意,不是内存资源)
read()方法从输入流读取数据的下一个字节,返回一个个的字节。
byte是可以直接提升转成int的。
read(byte[] b)方法是丢到一个字节数组中,一段一段地去读,返回读取了多少个。
OutputStream
OutputStream跟InputStream是成对的。
OutputStream抽象类也实现了Closeable接口:
public abstract class OutputStream implements Closeable, Flushable {......}
Flushable用来强制刷新,防止驻留在内存中的数据不出去。
使用Closeable把它关了也会强制刷新。
如果一个文件时不断地不间断的去读,建议每读一次flush一下。最后一次可以不用flush,因为会用Closeable进行关闭。
OutputStream类有一个flush方法,用来刷新此输出流并强制任何缓冲的输出字节被写出。
write(int b)方法:一个一个字节地去写。
write(byte b[])方法:装了字节数组,一段一段地去写。
write(byte b[], int off, int len)方法:指定b数组里面的一部分写数据。从指定的字节数组写入 len
个字节,从偏移 off
开始输出到此输出流。
OutputStream比InputStream多了flush方法。
Reader
Reader是用于读取字符流的抽象类。
字节流处理一切,字符流只能处理存文本。3
Reader抽象类也实现了Closeable接口,还实现了Readable接口:
public abstract class Reader implements Readable, Closeable {......}
Reader抽象类的close方法是关闭流并释放与之相关联的任何系统资源。
read()方法读取一个字符,一个字符可能是两个字节、一个字节、三个字节等。
read(char cbuf[])方法将字符读入数组,返回的是长度。
Writer
Writer是用于用于写入字符流的抽象类。
public abstract class Writer implements Appendable, Closeable, Flushable {......}
Appendable是用来写的。
写有两种方式:全覆盖和向后追加。
Writer抽象类也有close方和flush方法。
write方法可以直接写字符串作为参数: