跳转至

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 小练习

  1. 写一个程序:把 "你好,Java" 写入文件,再读出来打印
  2. 读一个文本文件,统计行数和字数
  3. 复制一个图片文件到新路径
  4. 定义类 ScoreData { String name; int score; },用 Gson 存到 JSON 再读回

本章小结

  • 简单读写:Files.readString / writeString
  • 大文件用流:BufferedReader/BufferedWriter
  • try-with-resources 自动关闭资源
  • 模组数据存储标配:JSON + Gson
  • 路径用 Paths.get,别硬编码斜杠

下一章:19 反射

🏠 返回总站