Java 其他流(常见特殊流)详解

除了 文件流(FileInputStream/FileOutputStream、FileReader/FileWriter)缓冲流(BufferedInputStream/BufferedOutputStream、BufferedReader/BufferedWriter),Java 还提供了许多 特殊的流 来满足不同的需求,如 数据流、转换流、对象流、打印流、标准输入输出流等


1. 数据流(DataInputStream / DataOutputStream)

作用

  • 让 Java 可以 读写基本数据类型(int、double、boolean等)字符串,而不仅仅是字节或字符。
  • 适用于 存储二进制数据(如数据库文件、序列化数据等)。

📌 1.1 DataOutputStream(数据输出流)

用于 写入基本数据类型 到文件,保证数据的格式不会丢失。

示例:使用 DataOutputStream 写入基本数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import java.io.*;

public class DataOutputStreamExample {
public static void main(String[] args) {
try (DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.bin"))) {
dos.writeInt(100); // 写入 int 类型
dos.writeDouble(99.99); // 写入 double 类型
dos.writeBoolean(true); // 写入 boolean 类型
dos.writeUTF("Hello, DataOutputStream!"); // 写入字符串(UTF-8 编码)
} catch (IOException e) {
e.printStackTrace();
}
}
}

📌 1.2 DataInputStream(数据输入流)

用于 读取基本数据类型,确保读取的数据与 DataOutputStream 写入的格式一致。

示例:使用 DataInputStream 读取基本数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import java.io.*;

public class DataInputStreamExample {
public static void main(String[] args) {
try (DataInputStream dis = new DataInputStream(new FileInputStream("data.bin"))) {
int num = dis.readInt();
double price = dis.readDouble();
boolean isAvailable = dis.readBoolean();
String message = dis.readUTF();

System.out.println("读取数据:" + num + ", " + price + ", " + isAvailable + ", " + message);
} catch (IOException e) {
e.printStackTrace();
}
}
}

🔹 适用场景

  • 读写 二进制数据(如数据库存储、网络传输)。
  • 避免 数据类型转换错误(如直接用 FileWriter 可能导致数据变成字符串格式)。

2. 转换流(InputStreamReader / OutputStreamWriter)

作用

  • 字节流 ↔ 字符流 转换,主要用于 解决编码问题(如 GBKUTF-8)。
  • 适用于处理文本数据,如从 网络流或文件流读取文本,并希望指定字符编码。

📌 2.1 InputStreamReader(字节流 -> 字符流)

示例:读取文件并指定编码格式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import java.io.*;

public class InputStreamReaderExample {
public static void main(String[] args) {
try (InputStreamReader isr = new InputStreamReader(new FileInputStream("test.txt"), "UTF-8");
BufferedReader br = new BufferedReader(isr)) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

📌 2.2 OutputStreamWriter(字符流 -> 字节流)

示例:写入文件并指定编码格式

1
2
3
4
5
6
7
8
9
10
11
12
13
import java.io.*;

public class OutputStreamWriterExample {
public static void main(String[] args) {
try (OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("output.txt"), "GBK");
BufferedWriter bw = new BufferedWriter(osw)) {
bw.write("你好,Java IO!");
bw.newLine();
} catch (IOException e) {
e.printStackTrace();
}
}
}

🔹 适用场景

  • 读取非 UTF-8 编码的文件(如 GBKISO-8859-1)。
  • 解决字符编码问题,保证不同编码的文件正确读写。

3. 对象流(ObjectInputStream / ObjectOutputStream)

作用

  • 序列化(Serialize):将 Java 对象保存到文件传输到网络
  • 反序列化(Deserialize):将 文件或网络中的数据恢复为 Java 对象

📌 3.1 ObjectOutputStream(对象序列化)

示例:将对象保存到文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import java.io.*;

class Person implements Serializable { // 必须实现 Serializable 接口
private static final long serialVersionUID = 1L; // 避免反序列化失败
String name;
int age;

public Person(String name, int age) {
this.name = name;
this.age = age;
}
}

public class ObjectOutputStreamExample {
public static void main(String[] args) {
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.dat"))) {
Person p = new Person("Alice", 25);
oos.writeObject(p); // 序列化对象
} catch (IOException e) {
e.printStackTrace();
}
}
}

📌 3.2 ObjectInputStream(对象反序列化)

示例:从文件读取对象

1
2
3
4
5
6
7
8
9
10
11
12
import java.io.*;

public class ObjectInputStreamExample {
public static void main(String[] args) {
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.dat"))) {
Person p = (Person) ois.readObject(); // 反序列化对象
System.out.println("姓名: " + p.name + ", 年龄: " + p.age);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}

🔹 适用场景

  • 保存对象到文件,如用户数据、游戏存档等。
  • 网络传输 Java 对象(如 RMI 远程调用)。

4. 标准输入/输出流(System.in / System.out)

作用

  • System.in 标准输入流,通常是 键盘输入
  • System.out 标准输出流,通常是 控制台输出

📌 4.1 使用 Scanner 读取标准输入

1
2
3
4
5
6
7
8
9
10
import java.util.Scanner;

public class StandardInputExample {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("请输入你的名字:");
String name = scanner.nextLine();
System.out.println("你好, " + name + "!");
}
}

5. 打印流(PrintStream / PrintWriter)

作用

  • PrintStreamPrintWriter 用于 格式化打印(如 System.out.println())。
  • 自动刷新,适用于 日志记录、控制台输出等

📌 5.1 使用 PrintWriter 写入文件

1
2
3
4
5
6
7
8
9
10
11
12
import java.io.*;

public class PrintWriterExample {
public static void main(String[] args) {
try (PrintWriter pw = new PrintWriter(new FileWriter("log.txt"), true)) {
pw.println("日志信息: 程序启动...");
pw.println("日志信息: 运行中...");
} catch (IOException e) {
e.printStackTrace();
}
}
}

🔹 适用场景

  • 日志文件(比 FileWriter 更方便)。
  • 格式化输出,如 printf()