IO流

作用: 读写文件中的数据(读写文件, 或网络中的数据等)
几个问题: 谁在读?谁在写?以什么为参照物看读写方向?程序或者内存
分类
- 按流的方向分
- 输入流: 程序–>文件
- 输出流: 文件–>程序
- 按操作文件类型
- 字节流: 所有类型文件
- 字符流: 纯文本文件(简单理解就是用记事本打开能读懂的文件, .docx这种不算)
- 按流的方向分
IO流体系
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38%%{init: {'theme': 'base', 'themeVariables': { 'fontFamily': 'Microsoft YaHei'}}}%%
graph TD
A[IO流体系] --> B[字节流]
A --> C[字符流]
B --> D[字节输入流]
B --> E[字节输出流]
D --> F[InputStream]
F --> F1[FileInputStream]
F --> F2[ByteArrayInputStream]
F --> F3[FilterInputStream]
F3 --> F31[BufferedInputStream]
F3 --> F32[DataInputStream]
E --> G[OutputStream]
G --> G1[FileOutputStream]
G --> G2[ByteArrayOutputStream]
G --> G3[FilterOutputStream]
G3 --> G31[BufferedOutputStream]
G3 --> G32[DataOutputStream]
G3 --> G33[PrintStream]
C --> H[字符输入流]
C --> I[字符输出流]
H --> J[Reader]
J --> J1[InputStreamReader]
J1 --> J11[FileReader]
J --> J2[BufferedReader]
J --> J3[StringReader]
I --> K[Writer]
K --> K1[OutputStreamWriter]
K1 --> K11[FileWriter]
K --> K2[BufferedWriter]
K --> K3[PrintWriter]
K --> K4[StringWriter]字节流
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21%%{init: {'theme': 'base', 'themeVariables': { 'fontFamily': 'Microsoft YaHei'}}}%%
graph TD
A[字节流] --> B[字节输入流 InputStream]
A --> C[字节输出流 OutputStream]
B --> B1[FileInputStream]
B --> B2[ByteArrayInputStream]
B --> B3[FilterInputStream]
B3 --> B31[BufferedInputStream]
B3 --> B32[DataInputStream]
B --> B4[ObjectInputStream]
B --> B5[PipedInputStream]
C --> C1[FileOutputStream]
C --> C2[ByteArrayOutputStream]
C --> C3[FilterOutputStream]
C3 --> C31[BufferedOutputStream]
C3 --> C32[DataOutputStream]
C3 --> C33[PrintStream]
C --> C4[ObjectOutputStream]
C --> C5[PipedOutputStream]字符流
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17%%{init: {'theme': 'base', 'themeVariables': { 'fontFamily': 'Microsoft YaHei'}}}%%
graph TD
D[字符流] --> E[字符输入流 Reader]
D --> F[字符输出流 Writer]
E --> E1[InputStreamReader]
E1 --> E11[FileReader]
E --> E2[BufferedReader]
E --> E3[StringReader]
E --> E4[PipedReader]
F --> F1[OutputStreamWriter]
F1 --> F11[FileWriter]
F --> F2[BufferedWriter]
F --> F3[PrintWriter]
F --> F4[StringWriter]
F --> F5[PipedWriter]
字节流—-以FileOutputStream为例
基本用法
- 创建流对象
- 读/写数据
- 释放资源(用try_with_resources语法可以不用手动写释放资源代码)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16public class FOS {
public static void main(String[] args) {
File newFile = new File("C:\\Users\\minmin\\Desktop\\newFile.txt");
try {
boolean isCreated = newFile.createNewFile();
if (isCreated) {
// 若文件不存在, 而父级文件夹存在时, 会创建文件
try (FileOutputStream fos = new FileOutputStream(newFile)) {
fos.write("<UNK>".getBytes());
}
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}细节
- 如果文件已经存在, 会清空文件重写
- 输入整数, 会被当成ASCII码转写为字符
- 如果不释放流资源, 文件会一直处于占用状态
- 释放资源的语句应该写在finally块中
换行和续写
换行
续写: 在同一个输出流中再次调用write()即可; 如果是在已有的文件内容基础上续写, 创建输出流时续写开关应为true
1
2
3fos.write("9789newFile".getBytes());
fos.write("\r\n".getBytes());
fos.write("89".getBytes());
循环读取
1
2
3
4int ch;
while ((ch = fis.read()) != -1) {
System.out.print((char) ch);
}
字符集
- GBK: 两个字节存一个字符, 由于需要与ASCII兼容, 同时为了区分中英文, 中文二进制编码统一以1开头填充, ASCII字符统一以0填充高位