IO流¶
📖 章节简介¶
本章将介绍Java的IO流操作,包括文件读写、字节流和字符流的使用。
上图对比了字节流与字符流两大体系,帮助快速选择合适的读写方案。
📁 文件操作¶
1. File类¶
Java
// File类使用
import java.io.File;
import java.io.IOException;
public class FileExample {
public static void main(String[] args) throws IOException {
// 创建File对象
File file = new File("test.txt");
// 创建文件
if (!file.exists()) {
boolean created = file.createNewFile();
System.out.println("文件创建: " + created);
}
// 创建目录
File dir = new File("testdir");
if (!dir.exists()) {
boolean created = dir.mkdir();
System.out.println("目录创建: " + created);
}
// 获取文件信息
System.out.println("\n文件信息:");
System.out.println("文件名: " + file.getName());
System.out.println("路径: " + file.getPath());
System.out.println("绝对路径: " + file.getAbsolutePath());
System.out.println("大小: " + file.length() + "字节");
System.out.println("可读: " + file.canRead());
System.out.println("可写: " + file.canWrite());
System.out.println("是否文件: " + file.isFile());
System.out.println("是否目录: " + file.isDirectory());
// 列出目录内容
File currentDir = new File(".");
System.out.println("\n当前目录内容:");
String[] files = currentDir.list();
for (String f : files) {
System.out.println(f);
}
// 删除文件
if (file.exists()) {
boolean deleted = file.delete();
System.out.println("\n文件删除: " + deleted);
}
}
}
🔄 字节流¶
1. FileInputStream和FileOutputStream¶
Java
// 字节流
import java.io.*;
public class ByteStreamExample {
public static void main(String[] args) {
// 写入文件
try (FileOutputStream fos = new FileOutputStream("output.txt")) {
String text = "Hello, World!";
fos.write(text.getBytes());
System.out.println("写入成功");
} catch (IOException e) {
System.out.println("写入失败: " + e.getMessage());
}
// 读取文件
try (FileInputStream fis = new FileInputStream("output.txt")) {
int data;
System.out.println("\n读取内容:");
while ((data = fis.read()) != -1) {
System.out.print((char) data);
}
} catch (IOException e) {
System.out.println("读取失败: " + e.getMessage());
}
// 缓冲读写
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream("output.txt"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copy.txt"))) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = bis.read(buffer)) != -1) {
bos.write(buffer, 0, bytesRead);
}
System.out.println("\n\n文件复制成功");
} catch (IOException e) {
System.out.println("复制失败: " + e.getMessage());
}
}
}
2. DataInputStream和DataOutputStream¶
Java
// 数据流
import java.io.*;
public class DataStreamExample {
public static void main(String[] args) {
// 写入数据
try (DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.dat"))) {
dos.writeInt(100);
dos.writeDouble(3.14);
dos.writeUTF("Hello");
dos.writeBoolean(true);
System.out.println("数据写入成功");
} catch (IOException e) {
System.out.println("写入失败: " + e.getMessage());
}
// 读取数据
try (DataInputStream dis = new DataInputStream(new FileInputStream("data.dat"))) {
int intValue = dis.readInt();
double doubleValue = dis.readDouble();
String stringValue = dis.readUTF();
boolean booleanValue = dis.readBoolean();
System.out.println("\n读取数据:");
System.out.println("int: " + intValue);
System.out.println("double: " + doubleValue);
System.out.println("String: " + stringValue);
System.out.println("boolean: " + booleanValue);
} catch (IOException e) {
System.out.println("读取失败: " + e.getMessage());
}
}
}
📝 字符流¶
1. FileReader和FileWriter¶
Java
// 字符流
import java.io.*;
public class CharStreamExample {
public static void main(String[] args) {
// 写入文件
try (FileWriter writer = new FileWriter("text.txt")) {
writer.write("Hello, World!\n");
writer.write("这是一个文本文件。");
System.out.println("写入成功");
} catch (IOException e) {
System.out.println("写入失败: " + e.getMessage());
}
// 读取文件
try (FileReader reader = new FileReader("text.txt")) {
int data;
System.out.println("\n读取内容:");
while ((data = reader.read()) != -1) {
System.out.print((char) data);
}
} catch (IOException e) {
System.out.println("读取失败: " + e.getMessage());
}
// 缓冲读写
try (BufferedReader br = new BufferedReader(new FileReader("text.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("copy.txt"))) {
String line;
System.out.println("\n\n逐行读取:");
while ((line = br.readLine()) != null) {
System.out.println(line);
bw.write(line);
bw.newLine();
}
System.out.println("文件复制成功");
} catch (IOException e) {
System.out.println("复制失败: " + e.getMessage());
}
}
}
2. PrintWriter¶
Java
// PrintWriter使用
import java.io.*;
public class PrintWriterExample {
public static void main(String[] args) {
try (PrintWriter pw = new PrintWriter(new FileWriter("print.txt"))) {
// 写入各种类型的数据
pw.println("Hello, World!");
pw.printf("姓名: %s, 年龄: %d%n", "张三", 25);
pw.printf("成绩: %.2f%n", 95.5);
pw.print("这是最后一行");
System.out.println("写入成功");
} catch (IOException e) {
System.out.println("写入失败: " + e.getMessage());
}
}
}
🎯 对象序列化¶
1. Serializable接口¶
Java
// 可序列化类
import java.io.Serializable;
public class Person implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + "}";
}
}
// 序列化和反序列化
import java.io.*;
public class SerializationExample {
public static void main(String[] args) {
// 序列化对象
Person person = new Person("张三", 25);
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.dat"))) {
oos.writeObject(person);
System.out.println("对象序列化成功");
} catch (IOException e) {
System.out.println("序列化失败: " + e.getMessage());
}
// 反序列化对象
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.dat"))) {
Person deserializedPerson = (Person) ois.readObject();
System.out.println("\n对象反序列化成功");
System.out.println("反序列化对象: " + deserializedPerson);
} catch (IOException | ClassNotFoundException e) {
System.out.println("反序列化失败: " + e.getMessage());
}
}
}
💡 最佳实践¶
1. 资源管理¶
Java
// 资源管理最佳实践
public class ResourceManagement {
// ✅ 好的做法:使用try-with-resources
public void readFile1() {
try (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
System.out.println("读取失败");
}
}
// ❌ 不好的做法:手动关闭资源
public void readFile2() {
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader("file.txt"));
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
System.out.println("读取失败");
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
System.out.println("关闭失败");
}
}
}
}
}
2. 性能优化¶
Java
// IO性能优化
public class IOOptimization {
// ✅ 好的做法:使用缓冲流
public void copyFile1() {
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream("input.txt"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("output.txt"))) {
byte[] buffer = new byte[8192];
int bytesRead;
while ((bytesRead = bis.read(buffer)) != -1) {
bos.write(buffer, 0, bytesRead);
}
} catch (IOException e) {
System.out.println("复制失败");
}
}
// ❌ 不好的做法:不使用缓冲流
public void copyFile2() {
try (FileInputStream fis = new FileInputStream("input.txt");
FileOutputStream fos = new FileOutputStream("output.txt")) {
int data;
while ((data = fis.read()) != -1) {
fos.write(data);
}
} catch (IOException e) {
System.out.println("复制失败");
}
}
}
📝 练习题¶
基础题¶
- Java的IO流有哪些类型?
- 字节流和字符流有什么区别?
- 如何使用try-with-resources?
进阶题¶
- 实现文件复制功能。
- 使用缓冲流提高IO性能。
- 实现对象序列化。
实践题¶
- 创建一个文本编辑器。
- 实现一个文件管理工具。
- 构建一个简单的日志系统。
📚 推荐阅读¶
🔗 下一章¶
多线程 - 学习Java的多线程编程。