《掌握 Java:从基础到高级概念的综合指南》(5/15)
目录
1. 引言
2. Java I/O 概述
3. 字节流
3.1 InputStream 和 OutputStream
3.1.1 FileInputStream 和 FileOutputStream
4. 字符流
4.1 Reader 和 Writer
4.1.1 FileReader 和 FileWriter
5. 缓冲流
5.1 BufferedReader 和 BufferedWriter
6. 序列化与反序列化
6.1 对象的序列化与反序列化
7. Java NIO (New Input/Output)
7.1 NIO 的基本组件
8. 字节流与字符流对比总结
9. 结论
Java 中的输入与输出 (I/O) 流
1. 引言
输入与输出 (I/O) 是 Java 编程中的重要组成部分,I/O 操作使得程序可以与外部环境进行交互,例如读取文件内容或将数据写入文件。Java 提供了丰富的 I/O API,用于处理不同类型的数据输入和输出,包括字节流、字符流、缓冲流、以及 NIO(New Input/Output)。本篇文章将深入探讨 Java 中的 I/O 操作,详细介绍字节流与字符流的区别、文件处理、序列化与反序列化,以及 NIO 的使用。
2. Java I/O 概述
Java I/O 主要通过 java.io 包提供的各种类和接口来实现,最基本的 I/O 操作是通过流来完成的。流可以看作是数据的顺序传输通道。
-
字节流 (Byte Stream):用于处理 8 位字节的数据,适合于处理如图像、音频等二进制文件。
-
输入字节流:
InputStream
-
输出字节流:
OutputStream
-
-
字符流 (Character Stream):用于处理 16 位字符的数据,适合于处理文本文件。
-
输入字符流:
Reader
-
输出字符流:
Writer
-
3. 字节流
3.1 InputStream 和 OutputStream
InputStream 和 OutputStream 是字节流的两个抽象基类,分别用于处理输入和输出操作。
3.1.1 FileInputStream 和 FileOutputStream
FileInputStream
用于从文件中读取字节,FileOutputStream
用于向文件中写入字节。
代码示例:使用 FileInputStream 和 FileOutputStream
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class ByteStreamExample {
public static void main(String[] args) {
try (FileInputStream fis = new FileInputStream("input.txt");
FileOutputStream fos = new FileOutputStream("output.txt")) {
int data;
while ((data = fis.read()) != -1) {
fos.write(data); // 将数据写入 output.txt
}
} catch (IOException e) {
System.out.println("I/O error: " + e.getMessage());
}
}
}
-
代码解析:
-
FileInputStream
读取input.txt
文件中的字节数据,FileOutputStream
将其写入到output.txt
中。 -
使用了 Java 7 的
try-with-resources
语法,确保资源在使用后自动关闭。
-
4. 字符流
4.1 Reader 和 Writer
Reader 和 Writer 是字符流的两个抽象基类,分别用于处理字符输入和输出操作。
4.1.1 FileReader 和 FileWriter
FileReader
和 FileWriter
分别用于读取和写入文本文件。
代码示例:使用 FileReader 和 FileWriter
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class CharacterStreamExample {
public static void main(String[] args) {
try (FileReader reader = new FileReader("input.txt");
FileWriter writer = new FileWriter("output.txt")) {
int data;
while ((data = reader.read()) != -1) {
writer.write(data); // 将数据写入 output.txt
}
} catch (IOException e) {
System.out.println("I/O error: " + e.getMessage());
}
}
}
-
代码解析:
-
FileReader
从input.txt
中读取字符数据,FileWriter
将其写入到output.txt
。 -
适用于文本文件的处理,能够正确处理字符数据。
-
5. 缓冲流
缓冲流用于提高 I/O 操作的效率,通过减少与底层设备之间的物理读写次数来提升性能。
5.1 BufferedReader 和 BufferedWriter
BufferedReader 和 BufferedWriter 分别用于字符流的输入和输出操作,提供了缓冲功能以提高读写效率。
代码示例:使用 BufferedReader 和 BufferedWriter
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class BufferedStreamExample {
public static void main(String[] args) {
try (BufferedReader br = new BufferedReader(new FileReader("input.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("output.txt"))) {
String line;
while ((line = br.readLine()) != null) {
bw.write(line);
bw.newLine(); // 换行
}
} catch (IOException e) {
System.out.println("I/O error: " + e.getMessage());
}
}
}
-
代码解析:
-
BufferedReader
提供了readLine()
方法,可以按行读取文本。 -
BufferedWriter
提供了newLine()
方法,用于换行。
-
6. 序列化与反序列化
序列化是将对象的状态转换为字节流的过程,反序列化则是从字节流恢复对象的状态。Java 提供了 Serializable
接口来实现序列化。
6.1 对象的序列化与反序列化
代码示例:对象的序列化与反序列化
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.IOException;
import java.io.Serializable;
class Person implements Serializable {
private static final long serialVersionUID = 1L;
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + "}";
}
}
public class SerializationExample {
public static void main(String[] args) {
Person person = new Person("Alice", 30);
// 序列化
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.ser"))) {
oos.writeObject(person);
} catch (IOException e) {
System.out.println("Serialization error: " + e.getMessage());
}
// 反序列化
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.ser"))) {
Person deserializedPerson = (Person) ois.readObject();
System.out.println("Deserialized Person: " + deserializedPerson);
} catch (IOException | ClassNotFoundException e) {
System.out.println("Deserialization error: " + e.getMessage());
}
}
}
-
代码解析:
-
Person
类实现了Serializable
接口,表明该类的对象可以被序列化。 -
使用
ObjectOutputStream
将对象写入文件 (person.ser
),使用ObjectInputStream
从文件中读取对象。
-
7. Java NIO (New Input/Output)
Java NIO 是 Java 1.4 引入的一套新的 I/O API,提供了非阻塞 I/O 操作,提高了 I/O 操作的性能和效率。
7.1 NIO 的基本组件
-
Channel:用于数据的读写,类似于传统 I/O 的流。
-
Buffer:用于存储数据,所有数据的读写都要通过缓冲区进行。
-
Selector:用于监控多个通道的事件(例如读、写、连接等),用于实现非阻塞 I/O。
代码示例:使用 NIO 读取文件
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.charset.StandardCharsets;
import java.util.List;
public class NIOExample {
public static void main(String[] args) {
Path path = Paths.get("input.txt");
try {
List<String> lines = Files.readAllLines(path, StandardCharsets.UTF_8);
for (String line : lines) {
System.out.println(line);
}
} catch (IOException e) {
System.out.println("I/O error: " + e.getMessage());
}
}
}
-
代码解析:
-
使用
Files
类提供的静态方法readAllLines()
从文件中读取所有行,方便快捷。 -
Path
和Paths
类用于表示文件路径,取代了传统的File
类。
-
8. 字节流与字符流对比总结
特性 | 字节流 (InputStream/OutputStream) | 字符流 (Reader/Writer) |
---|---|---|
适用场景 | 处理二进制数据,如图片、音频等 | 处理文本数据,如 .txt 文件 |
数据处理单位 | 8 位字节 | 16 位字符 |
主要类 | FileInputStream , FileOutputStream | FileReader , FileWriter |
9. 结论
Java 中的 I/O 流提供了丰富的 API 来处理不同类型的数据输入与输出,本文详细介绍了字节流、字符流、缓冲流、对象序列化与反序列化,以及 Java NIO 的基础用法。通过这些知识,开发者可以灵活地处理文件、网络、数据等各种 I/O 操作,从而使应用程序与外部环境高效交互。在后续的文章中,我们将继续探讨 Java 中更为高级的特性,如泛型、注解、多线程等内容,以帮助您更全面地掌握 Java 编程。
希望本篇文章能够帮助你深入理解 Java 中的输入与输出操作。如果有任何疑问或想了解更多细节,欢迎在评论区留言!