Java I/O 流介绍
Java学习资料
Java学习资料
Java学习资料
一、引言
在 Java 编程中,I/O(Input/Output)流是处理输入和输出操作的核心机制。它允许程序与外部设备(如文件、网络连接、键盘、显示器等)进行数据交互。通过使用 I/O 流,我们可以读取数据到程序中,也可以将程序中的数据写入到外部设备。Java 的 I/O 流体系非常庞大且复杂,但它提供了丰富的类和接口,使得开发者能够方便地处理各种不同类型的输入输出任务。
二、I/O 流的基本概念
1. 流的定义
流是一种抽象的概念,它代表了数据的序列。数据就像水流一样,从一个地方流向另一个地方。在 Java 中,流可以是输入流,用于从外部源读取数据;也可以是输出流,用于将数据写入到外部目标。
2. 流的分类
按流向分类
输入流:用于从数据源读取数据,如从文件、网络等读取数据。在 Java 中,所有输入流类都继承自 InputStream(字节输入流)或 Reader(字符输入流)。
输出流:用于将数据写入到目标设备,如写入文件、发送到网络等。所有输出流类都继承自 OutputStream(字节输出流)或 Writer(字符输出流)。
按处理数据的单位分类
字节流:以字节为单位进行数据处理,适用于处理二进制数据,如图片、音频、视频等。InputStream 和 OutputStream 是字节流的抽象基类。
字符流:以字符为单位进行数据处理,适用于处理文本数据。Reader 和 Writer 是字符流的抽象基类。
三、字节流
1. InputStream 类
InputStream 是所有字节输入流的抽象基类,它定义了基本的读取方法。常用的 InputStream 子类有 FileInputStream、ByteArrayInputStream 等。下面是一个使用 FileInputStream 读取文件的示例:
import java.io.FileInputStream;
import java.io.IOException;
public class FileInputStreamExample {
public static void main(String[] args) {
try (FileInputStream fis = new FileInputStream("test.txt")) {
int data;
while ((data = fis.read()) != -1) {
System.out.print((char) data);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
2. OutputStream 类
OutputStream 是所有字节输出流的抽象基类,它定义了基本的写入方法。常用的 OutputStream 子类有 FileOutputStream、ByteArrayOutputStream 等。下面是一个使用 FileOutputStream 写入文件的示例:
import java.io.FileOutputStream;
import java.io.IOException;
public class FileOutputStreamExample {
public static void main(String[] args) {
try (FileOutputStream fos = new FileOutputStream("test.txt")) {
String data = "Hello, World!";
byte[] bytes = data.getBytes();
fos.write(bytes);
} catch (IOException e) {
e.printStackTrace();
}
}
}
四、字符流
1. Reader 类
Reader 是所有字符输入流的抽象基类,它提供了以字符为单位读取数据的方法。常用的 Reader 子类有 FileReader、BufferedReader 等。下面是一个使用 BufferedReader 读取文件的示例:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class BufferedReaderExample {
public static void main(String[] args) {
try (BufferedReader br = new BufferedReader(new FileReader("test.txt"))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
2. Writer 类
Writer 是所有字符输出流的抽象基类,它提供了以字符为单位写入数据的方法。常用的 Writer 子类有 FileWriter、BufferedWriter 等。下面是一个使用 BufferedWriter 写入文件的示例:
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
public class BufferedWriterExample {
public static void main(String[] args) {
try (BufferedWriter bw = new BufferedWriter(new FileWriter("test.txt"))) {
String data = "Hello, Java!";
bw.write(data);
} catch (IOException e) {
e.printStackTrace();
}
}
}
五、缓冲流
缓冲流是一种装饰器流,它可以提高 I/O 操作的效率。缓冲流内部使用了一个缓冲区,减少了与底层设备的直接交互次数。常见的缓冲流有 BufferedInputStream、BufferedOutputStream、BufferedReader 和 BufferedWriter。例如,在前面的字符流示例中,我们使用了 BufferedReader 和 BufferedWriter 来提高文件读写的效率。
六、对象流
对象流允许我们将对象直接写入到流中,或者从流中读取对象。ObjectInputStream 和 ObjectOutputStream 是实现对象序列化和反序列化的关键类。要使一个类的对象能够被序列化,该类必须实现 Serializable 接口。下面是一个对象序列化和反序列化的示例:
import java.io.*;
class Person implements Serializable {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
public class ObjectStreamExample {
public static void main(String[] args) {
// 序列化对象
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.ser"))) {
Person person = new Person("John", 30);
oos.writeObject(person);
} catch (IOException e) {
e.printStackTrace();
}
// 反序列化对象
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.ser"))) {
Person person = (Person) ois.readObject();
System.out.println("Name: " + person.getName() + ", Age: " + person.getAge());
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
七、总结
Java 的 I/O 流体系提供了丰富的类和接口,使得开发者能够方便地处理各种输入输出任务。字节流适用于处理二进制数据,字符流适用于处理文本数据。缓冲流可以提高 I/O 操作的效率,对象流则允许我们进行对象的序列化和反序列化。在实际开发中,我们需要根据具体的需求选择合适的流类来完成数据的读写操作。同时,为了避免资源泄漏,我们应该使用 try-with-resources 语句来自动关闭流资源。