编程自学指南:java程序设计开发,Java I/O流,为什么需要I/O流?,Java I/O体系结构,字节流,字符流,对象流与序列化
编程自学指南:java程序设计开发,Java I/O流
学习目标:
-
理解I/O流的核心概念与分类
-
掌握字节流、字符流及缓冲流的用法
-
能够通过I/O流实现文件读写与数据传输
-
避免资源泄漏与编码相关的常见错误
一、课程引入
1.1 为什么需要I/O流?
-
应用场景:
-
文件读写(如读取配置文件、保存日志)
-
网络数据传输(如上传下载文件)
-
控制台输入输出(如用户交互)
-
-
核心作用:实现数据源与程序之间的数据传输
1.2 Java I/O体系结构
-
按数据类型分类:
-
字节流:
InputStream
/OutputStream
(处理图片、视频等二进制文件) -
字符流:
Reader
/Writer
(处理文本文件,自动处理编码)
-
-
按功能分类:
-
节点流:直接操作数据源(如
FileInputStream
) -
处理流:包装节点流增强功能(如
BufferedInputStream
)
-
二、字节流
2.1 FileInputStream与FileOutputStream
案例1:复制图片文件
try (InputStream is = new FileInputStream("input.jpg");
OutputStream os = new FileOutputStream("output.jpg")) {
byte[] buffer = new byte[1024];
int len;
while ((len = is.read(buffer)) != -1) {
os.write(buffer, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
}
2.2 字节缓冲流(BufferedInputStream/BufferedOutputStream)
案例2:高效文件复制
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream("input.txt"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("output.txt"))) {
int data;
while ((data = bis.read()) != -1) {
bos.write(data);
}
}
三、字符流
3.1 FileReader与FileWriter
案例3:读取并写入文本文件
try (Reader reader = new FileReader("input.txt");
Writer writer = new FileWriter("output.txt")) {
char[] buffer = new char[1024];
int len;
while ((len = reader.read(buffer)) != -1) {
writer.write(buffer, 0, len);
}
}
3.2 字符缓冲流(BufferedReader/BufferedWriter)
案例4:逐行读取文件内容
try (BufferedReader br = new BufferedReader(new FileReader("log.txt"))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
}
四、对象流与序列化
4.1 序列化与反序列化
-
要求:实现
Serializable
接口
public class User implements Serializable {
private String name;
private transient String password; // transient修饰的字段不序列化
// 构造方法、getter/setter
}
4.2 ObjectInputStream/ObjectOutputStream
案例5:保存与恢复对象
// 序列化
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("user.dat"))) {
oos.writeObject(new User("张三", "123456"));
}
// 反序列化
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("user.dat"))) {
User user = (User) ois.readObject();
System.out.println(user.getName()); // 输出"张三"
}
五、NIO与Files类(Java 7+)
5.1 Path与Files工具类
案例6:快速读写文件
Path path = Paths.get("data.txt");
// 写入文件
Files.write(path, "Hello Java".getBytes());
// 读取文件
List<String> lines = Files.readAllLines(path);
lines.forEach(System.out::println);
六、综合案例
6.1 案例7:日志记录系统
public class Logger {
public static void log(String message) {
try (BufferedWriter writer = new BufferedWriter(new FileWriter("app.log", true))) {
writer.write(LocalDateTime.now() + " - " + message);
writer.newLine();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// 使用
Logger.log("用户登录成功");
6.2 案例8:文件加密工具
try (InputStream is = new FileInputStream("origin.txt");
OutputStream os = new FileOutputStream("encrypted.txt")) {
int data;
while ((data = is.read()) != -1) {
os.write(data ^ 0xFF); // 简单异或加密
}
}
七、常见错误与最佳实践
7.1 常见错误
-
错误1:未关闭流导致资源泄漏
FileInputStream fis = new FileInputStream("test.txt"); // 忘记调用fis.close()
错误2:字符编码不一致导致乱码
new FileReader("gbk.txt"); // 默认使用UTF-8读取GBK文件会乱码
7.2 最佳实践
-
使用try-with-resources自动关闭资源
-
明确指定字符编码(如
StandardCharsets.UTF_8
)
八、总结与练习
8.1 总结
-
字节流:处理二进制文件(如图片、视频)
-
字符流:处理文本文件(注意编码)
-
缓冲流:提升I/O性能
-
对象流:实现序列化与反序列化
8.2 课后任务
-
编写程序统计文本文件中各单词的出现次数
-
实现一个文件加密解密工具(支持自定义密钥)
-
预习下一节课:多线程编程
8.3 扩展挑战
-
用NIO的
Files.walk
方法实现递归遍历目录文件