18 文件与 IO¶
本章目标¶
- 掌握 File / Path 操作
- 掌握读写文本文件
- 掌握 try-with-resources 自动关闭
- 了解 NIO 与序列化
18.1 File 与 Path¶
传统 File¶
import java.io.File;
File f = new File("config.json");
f.exists(); // 是否存在
f.isFile(); // 是否文件
f.isDirectory(); // 是否目录
f.getName(); // 文件名
f.getPath(); // 路径
f.length(); // 字节大小
f.delete(); // 删除(成功返回 true)
f.mkdirs(); // 创建目录(含父目录)
f.listFiles(); // 列出子文件/目录
Path(Java 7+,推荐)¶
import java.nio.file.*;
Path p = Paths.get("config", "mods", "ffsmod.json"); // 多段路径
Path full = Paths.get("/www/wwwroot/ffsmcserver/config.json");
Paths.get(".").toAbsolutePath(); // 绝对路径
Files.exists(p);
Files.createDirectories(p.getParent()); // 创建父目录
Files.size(p);
Files.deleteIfExists(p);
18.2 读写文本文件(简单方式)¶
读整个文件¶
import java.nio.file.*;
try {
String content = Files.readString(Paths.get("data.txt"));
System.out.println(content);
} catch (IOException e) {
e.printStackTrace();
}
写整个文件¶
Files.writeString(Paths.get("data.txt"), "要写入的内容");
Files.writeString(Paths.get("log.txt"), "新的一行\n", StandardOpenOption.APPEND); // 追加
按行读¶
List<String> lines = Files.readAllLines(Paths.get("data.txt"));
for (String line : lines) {
System.out.println(line);
}
模组里最常用
存配置、存进度、存玩家数据,Files.readString / writeString 配合 JSON 库(Gson)就是最常用的套路。
18.3 流(Stream)方式读写¶
处理大文件、需要逐字节处理时用流:
import java.io.*;
// 写:FileWriter + BufferedWriter
try (BufferedWriter writer = new BufferedWriter(new FileWriter("out.txt"))) {
writer.write("第一行");
writer.newLine();
writer.write("第二行");
} catch (IOException e) {
e.printStackTrace();
}
// 读:FileReader + BufferedReader
try (BufferedReader reader = new BufferedReader(new FileReader("out.txt"))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
try-with-resources
try (资源) { ... } 语法:资源实现 AutoCloseable,代码块结束自动 close(),不用手动关,也不会漏。
18.4 字节流与复制文件¶
// 复制文件(图片、二进制文件)
try (InputStream in = new FileInputStream("a.png");
OutputStream out = new FileOutputStream("b.png")) {
byte[] buffer = new byte[8192];
int len;
while ((len = in.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
}
// 或者直接一行
Files.copy(Paths.get("a.png"), Paths.get("b.png"), StandardCopyOption.REPLACE_EXISTING);
18.5 序列化与 JSON¶
Java 原生序列化(慎用)¶
// 对象 -> 字节流(类要实现 Serializable)
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("data.bin"));
oos.writeObject(playerData);
oos.close();
JSON(模组开发标配)¶
Minecraft 自带 Gson。存配置、存数据都用 JSON:
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
// 类
public class ModConfig {
public int maxLevel = 100;
public boolean enableFeature = true;
public String welcomeMessage = "欢迎";
}
// 写 JSON
ModConfig cfg = new ModConfig();
String json = new GsonBuilder().setPrettyPrinting().create().toJson(cfg);
Files.writeString(Paths.get("config/ffsmod.json"), json);
// 读 JSON
String content = Files.readString(Paths.get("config/ffsmod.json"));
ModConfig loaded = new Gson().fromJson(content, ModConfig.class);
18.6 实战:模组场景¶
// 模组配置读写(简化版)
public class ConfigManager {
private static final Path CONFIG_PATH = Paths.get("config", "ffsmod.json");
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
public static void save(ModConfig config) {
try {
Files.createDirectories(CONFIG_PATH.getParent());
Files.writeString(CONFIG_PATH, GSON.toJson(config));
} catch (IOException e) {
System.out.println("[FFSMod] 保存配置失败: " + e.getMessage());
}
}
public static ModConfig load() {
try {
return GSON.fromJson(Files.readString(CONFIG_PATH), ModConfig.class);
} catch (IOException e) {
return new ModConfig(); // 读取失败用默认配置
}
}
}
18.7 小练习¶
- 写一个程序:把
"你好,Java"写入文件,再读出来打印 - 读一个文本文件,统计行数和字数
- 复制一个图片文件到新路径
- 定义类
ScoreData { String name; int score; },用 Gson 存到 JSON 再读回
本章小结¶
- 简单读写:Files.readString / writeString
- 大文件用流:BufferedReader/BufferedWriter
- try-with-resources 自动关闭资源
- 模组数据存储标配:JSON + Gson
- 路径用 Paths.get,别硬编码斜杠
下一章:19 反射