You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何文件读取失败?实现Serializable后文本读写仍异常

嘿,我发现你的核心问题啦!

你现在是把Java对象序列化和普通文本文件读写这俩完全不同的东西搞混了,这才导致写入的不是文本、读取没内容的问题。

先掰正你的理解误区

  • Serializable接口是用来让Java对象转换成二进制字节流保存的,生成的是不可读的二进制文件,根本不是你要的文本格式。
  • 如果目标是读写人类可读的文本文件,完全不需要Serializable,也不用序列化相关的IO类,得用专门处理文本的Reader/Writer系列工具。

针对「读写文本文件」的修正代码

假设你要实现的是每行存一个字符串的文本文件读写,给你调整后的方法:

写入文本文件的方法

public static void writeText(ArrayList<String> content) {
    Frame f = new Frame();
    FileDialog foBox = new FileDialog(f, "保存文本文件", FileDialog.SAVE);
    foBox.setVisible(true);
    
    // 处理用户取消选择的情况
    if (foBox.getFile() == null) return;
    
    String filePath = foBox.getDirectory() + foBox.getFile();
    // 用try-with-resources自动关闭流,避免资源泄漏
    try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath))) {
        for (String line : content) {
            writer.write(line);
            writer.newLine(); // 每行结尾加换行符,保证文本格式正确
        }
    } catch (IOException e) {
        e.printStackTrace();
        JOptionPane.showMessageDialog(f, "写入失败:" + e.getMessage());
    }
}

读取文本文件的方法

public static ArrayList<String> readText() {
    ArrayList<String> read = new ArrayList<>();
    Frame f = new Frame();
    FileDialog foBox = new FileDialog(f, "读取文本文件", FileDialog.LOAD);
    foBox.setVisible(true);
    
    if (foBox.getFile() == null) return read;
    
    String filePath = foBox.getDirectory() + foBox.getFile();
    try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
        String line;
        // 逐行读取,直到文件末尾
        while ((line = reader.readLine()) != null) {
            read.add(line);
        }
    } catch (IOException e) {
        e.printStackTrace();
        JOptionPane.showMessageDialog(f, "读取失败:" + e.getMessage());
    }
    return read;
}

如果你其实是想做「对象序列化」(不是文本)

如果你本来的需求就是保存ArrayList对象的状态(不需要文本可读),那得用ObjectInputStream/ObjectOutputStream来处理,代码应该是这样的:

// 序列化写入ArrayList对象
public static void serializeList(ArrayList<String> list) {
    Frame f = new Frame();
    FileDialog foBox = new FileDialog(f, "序列化保存", FileDialog.SAVE);
    foBox.setVisible(true);
    if (foBox.getFile() == null) return;
    
    String filePath = foBox.getDirectory() + foBox.getFile();
    try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath))) {
        oos.writeObject(list);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

// 反序列化读取ArrayList对象
public static ArrayList<String> deserializeList() {
    ArrayList<String> list = new ArrayList<>();
    Frame f = new Frame();
    FileDialog foBox = new FileDialog(f, "序列化读取", FileDialog.LOAD);
    foBox.setVisible(true);
    if (foBox.getFile() == null) return list;
    
    String filePath = foBox.getDirectory() + foBox.getFile();
    try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath))) {
        // 注意强制类型转换
        list = (ArrayList<String>) ois.readObject();
    } catch (IOException | ClassNotFoundException e) {
        e.printStackTrace();
    }
    return list;
}

⚠️ 注意:这种方式生成的是二进制文件,用文本编辑器打开会是乱码,这是正常的,只有用上面的反序列化代码才能正确读取对象。

内容的提问来源于stack exchange,提问作者Amanda

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:48:31