Java I/O流
一、简介
I/O主要解决从数据源读入数据和将数据写入到目的地问题。数据源和目的地可以理解为IO流的两端。(这两端可以是文件或者网络连接)
字节流: InputStream/OutputStream。
字符流: Reader/Writer。
数据源与程序内存读写操作:
二、分类
2.1、按流的方向上
分为输入流InputStream或Reader,输出流OutputStream或Writer
任何从InputStream或Reader派生的类都有read()方法,用于读取单个字节或字节数组。
任何从OutputSteam或Writer派生的类都有write()方法,用于写单个字节或字节数组。
2.2、从操作字节还是操作字符的角度
面向字节流的类,基本都以XxxStream结尾。
面向字符流的类都以XxxReader或XxxWriter结尾。
这两种类型的流是可以转化的,有两个转化流的类,这个后面会说到。
2.3、一般在使用IO流的时候会有下面类似代码:
1 | FileInputStream inputStream = new FileInputStream(new File("a.txt")); |
这其实是一种装饰器模式的使用,IO流体系中使用了装饰器模式包装了各种功能流类
。
IO流体系中FilterInputStream/FilterOutStream
和FilterReader/FilterWriter
就是装饰器模式的接口类。
从该类向下包装了一些功能流类。有DataInputStream、BufferedInputStream、LineNumberInputStream、PushbackInputStream
等,当然还有输出的功能流类;面向字符的功能流类等。
下面几张图描述了整个IO流的继承体系结构:
InputStream流体系
OutputStream流体系
Reader体系
Writer体系
三、File其实是个工具类
File类其实不止是代表一个文件,它也能代表一个目录下的一组文件(代表一个文件路径)。
File类中最常用的方法:
1 | File.delete() // 删除文件或文件夹目录。 |
需要注意的是,不同系统对文件路径的分割符表是不一样的,比如Windows中是“\”,Linux是“/”。
而File类给我们提供了抽象的表示File.separator,屏蔽了系统层的差异。因此平时在代码中不要使用诸如“\”这种代表路径,可能造成Linux平台下代码执行错误。
示例:根据传入的规则,遍历得到目录中所有的文件构成的File对象数组
1 | public class Directory { |
提供了一些基础的输入流方法:
1 | //从数据中读入一个字节,并返回该字节,遇到流的结尾时返回-1 |
直接从InputStream继承的流,基本上对应了每种数据源类型。
| 类 | 功能 |
| :———————- | :————————————————— |
| ByteArrayInputStream | 将字节数组作为InputStream |
| StringBufferInputStream | 将String转成InputStream |
| FileInputStream | 从文件中读取内容 |
| PipedInputStream | 产生用于写入相关PipedOutputStream的数据。实现管道化 |
| SequenceInputStream | 将两个或多个InputStream对象转换成单一的InputStream |
| FilterInputStream | 抽象类,主要是作为“装饰器”的接口类,实现其他的功能流 |
4.2、OutputStream将程序内存中的数据写入到接收数据的一端。
1 | public abstract class OutputStream implements Closeable, Flushable {} |
同样地,OutputStream
也提供了一些基础流的实现,这些实现也可以和特定的目的地(接收端)对应起来,比如输出到字节数组或者是输出到文件/管道等。
类 | 功能 |
---|---|
ByteArrayOutputStream | 在内存中创建一个缓冲区,所有送往“流”的数据都要放在此缓冲区 |
FileOutputStream | 将数据写入文件 |
PipedOutputStream | 和PipedInputStream配合使用。实现管道化 |
FilterOutputStream | 抽象类,主要是作为“装饰器”的接口类,实现其他的功能流 |