12、IO流
1. I/O 流分类
-
按照数据流的方向
-
输入流:文件 程序
-
输出流:程序 文件
-
输入流和输出流都是站在程序的角度上来说的
-
按照处理数据单位
-
字节流
最原始的一个流,读出来的数据就是类似 01010101 这种最底层的数据表示形式;
按照一个字节一个字节来读
-
字符流
按照一个字符一个字符地往外读取数据(一个字符是 2 个字节)
-
-
按照功能
-
节点流
节点流可以从或向一个特定的地方(节点)读写数据,直接跟数据源相接
-
处理流
处理流用来包装节点流,是对一个已存在的流(节点流或处理流)的连接和封装,通过所封装的流的功能调用实现数据读写,不会直接与数据源相连
-
JDK 所提供的所有流类型位于包 java.io
内,都分别继承自以下四种抽象流类型:
-
输入流:
- InputStream(字节流)
- Reader(字符流)
-
输出流:
- OutputStream(字节流)
- Writer(字符流)
2. InputStream
-
凡是以 InputStream 结尾的流类型,都是以字节的形式向程序输入数据
-
继承自 InputStream 的流都是用于向程序中输入数据,且数据的单位为字节(8 bit)
InputStream 的基本方法:
-
int read() throws IOException
- 从输入流中读取一个字节的数据,每读取一个字节,就处理一个字节==(如果读取结束,返回的是 -1)== -
int read(byte b[]) throws IOException
- 从流中读取字节并存储在指定的数组中,然后再处理数组里面的数据==(如果读取结束返回 -1)== -
int read(byte b[], int off, int len) throws IOException
- 从输入流中读取最多 len 个字节,并将其存储在缓冲区数组 b 中,从偏移量 off 开始存储==(如果遇到流尾部,返回 -1)== -
long skip(long n) throws IOException
- 从输入流中跳过并丢弃 n 个字节的数据 -
int available() throws IOException
- 返回输入流中可用的字节数 -
void close() throws IOException
- 关闭输入流
3. OutputStream
- 继承自 OutputStream 的流是用于程序中输出数据,且数据的单位为字节(8 bit)
OutputStream 的方法:
void write(int b) throws IOException
- 将指定的字节写入输出流(写入低8位,忽略高24位)write(byte b[]) throws IOException
- 把字节数组中所有数据写入到输出流中void write(byte b[], int off, int len) throws IOException
- 将指定字节数组的一部分写入输出流,从偏移量off
开始,写入长度为len
的字节void flush() throws IOException
- 强制将输出流中存在的所有数据写入目标void close() throws IOException
- 关闭输出流
4. Reader
和 InputStream 一模一样,唯一的区别就在于读的数据单位不同
继承自 Reader 的流都是用于向程序中输入数据,且数据的单位为字符(16 bit)
Reader 的基本方法:
boolean ready() throws IOException
- 检查 Reader 流是否准备好读取
int read() throws IOException
- 从输入流中读取单个字符int read(char cbuf[]) throws IOException
- 从流中读取字符并存储在指定的数组中int read(char cbuf[], int off, int len) throws IOException
- 从流中读取 len 长度的字符数,并从 off 开始存储在指定的数组中long skip(long n) throws IOException
- 从流中丢弃指定数量的字符void close() throws IOException
- 关闭输入流
5. Writer
继承自Writer的流都是用于程序中输出数据,且数据的单位为字符(16 bit)
Writer 的基本方法:
void write(int c) throws IOException
- 写一个字符void write(char cbuf[]) throws IOException
- 写一个字符数组void write(char cbuf[], int off, int len) throws IOException
- 写一个字符数组的一部分,off 为开始索引,len 为字符个数void write(String str) throws IOException
- 写一个字符串void write(String str, int off, int len) throws IOException
- 写一个字符串的一部分,off 指定要写入的子串在 str 中的起始位置,len 指定要写入的子串的长度void flush() throws IOException
- 强制将输出流中存在的所有数据写入目标void close() throws IOException
- 关闭输出流
一定要及时关闭流,否则可能造成无法读写数据。
6. 处理流
6.1 缓冲流
缓冲流可分为以下 4 类:
-
BufferedReader
BufferedReader
提供了readLine()
方法用于读取一行字符串 -
BufferedWriter
BufferedWriter
提供了newLine()
用于写入一个行分隔符 -
BufferedInputStream
-
BufferedOutputStream
以 BufferedReader
类为例,其构造函数有:
BufferedReader(Reader in)
BufferedReader(Reader in, int sz)
- 其中参数 sz 表示缓冲区大小
对于输出的缓冲流,写出的数据会现在内存中缓存,使用
flush()
方法将会使内存中的数据立刻写出
6.2 转换流
转换流非常的有用,它可以把一个字节流转换成一个**字符流**。
转换流分为两种:
-
InputStreamReader
- 将
InputStream
流转换成Reader
流; - 需要和
InputStream
“套接”
- 将
-
OutputStreamWriter
-
将
OutputStream
流转换成Writer
流; -
需要和
OutputStream
“套接”
-
6.3 数据流
-
DataInputStream
继承自
InputStream
;需要”套接“在
InputStream
类型的节点流上构造函数:
DataInputStream(InputStream in)
-
DataOutputStream
继承自
OutputStream
;需要“套接”在
OutputStream
类型的节点流上构造函数:
DataOutputStream(OutputStream out)
6.4 打印流
PrintWriter
和PrintStream
都属于输出流,分别针对与字符和字节PrintWriter
和PrintStream
提供了重载的print()
方法和println()
方法,用于多种数据类型的输出PrintWriter
和PrintStream
的输出操作不会抛出异常,用户通过检测错误状态获取错误信息PrintWriter
和PrintStream
有自动flush
功能
6.5 对象流
直接将 Object 写入或读出
-
transient
关键字:用它来修饰的成员变量在序列化的时候不予考虑,也就是当成不存在 -
Serializable
接口:一个对象序列化的标记性接口,一个类只有实现了Serializable
接口,它的对象才能被序列化 -
Externalizable
接口:自定义序列化和反序列化,需要实现writeExternal()
和readExternal()
方法