【问题标题】:Serialization does not work with a custom linked list序列化不适用于自定义链表
【发布时间】:2013-01-06 01:39:52
【问题描述】:

所以这是我的问题: 对于一个项目,我必须创建一个自定义链表,我必须向其中添加节点并使用序列化将其保存/加载到磁盘和从磁盘加载 在我定义问题之前,这里有一些关于我的系统的事情

  • 我有一个作为节点数据的通用“客户文件”
  • 这存储在一个节点对象中,该对象充当列表的一个元素
  • 有一个客户文件类,其中存储了姓名和电子邮件地址等信息,以及各种获取和设置方法 - 这些都可以正常工作
  • 有一个节点类,其中包含获取和设置数据以及下一个方法,其中下一项是节点对象并充当列表中的下一项
  • 有一个带有添加、删除、修改、排序、搜索等方法的单链接类 - 它是自定义类,因此不实现任何 JAVA 预制列表。
  • 已经对所有类分别进行了大量测试并一起使用 - 这些方法是万无一失的 - 它们有效
  • 有一个主类用于用户和系统之间的主界面 - 它是一个 CLI 系统(命令行)
  • 它有一个保存列表到文件函数和从文件函数加载列表(在主类中),每个函数使用序列化或反序列化从磁盘保存/加载列表
  • 所有类都实现了可序列化接口
  • 主类中有一个“MAIN”方法,通过该方法运行 while 循环,允许用户以某种方式修改列表(例如添加记录、删除记录等...)
  • 列表在循环外加载,因此每次循环迭代时都不会清除它(同事之间的常见问题)
  • 我有一个系统密码,使用相同的方法将字符串保存到另一个文件位置,并且已经工作了数周 - 密码保存在该位置,可以随意访问、更改和删除
  • 这些加载/保存方法具有适当的 try/catch 方法来捕获任何异常

问题是每次我加载我的编程环境并想要查看列表时,我发现文件中的列表是“空的”并且不包含我上次添加/删除内容时的记录。

我添加记录并修改列表 - 与其他类一样容易 - 一旦添加这些,我调用打印函数,它只显示列表中的所有项目,这很好。

但是,在我关闭环境的那一刻,它们就丢失了,当我重新打开环境再次查看列表时,它是空的!

在查看保存这些类的文件夹时,我注意到每次运行程序时都会创建“shell”并保留在那里直到程序关闭/完成,但是“listData.ser”应该有保存的链表没有任何数据。

同样,密码文件包含保存完好的密码 - 所以我有点困惑为什么我的代码不起作用。

这是我的保存列表方法:

private static void saveListToFile(SinglyLinkedList lst) {
    try {
        ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream("ListData.ser"));
        os.writeObject(lst);
        os.flush();
        os.close();
    } 

    catch (FileNotFoundException e) {
        e.printStackTrace();
    }

    catch (IOException e) {
        e.printStackTrace();
    }
}

同样,加载列表方法类似,但使用对象输入流和文件输入流。

有什么建议吗?

附:我的主 while 循环有 400 多行代码,因此无法发布。

更新 1。 加载列表方法中的反序列化代码:

private static SinglyLinkedList loadListFromFile() {
    SinglyLinkedList lst = null;

    try {
        ObjectInputStream is = new ObjectInputStream(new FileInputStream("ListData.ser"));
        lst = (SinglyLinkedList) is.readObject();
        is.close();
    }

    catch(FileNotFoundException e) {
        e.printStackTrace();
    }

    catch(IOException e) {
        e.printStackTrace();
    }

    catch(ClassNotFoundException e) {
        e.printStackTrace();
    }

    return lst;
}

我不认为单链表类本身是问题(回复评论),复制也不可行,因为它也是超过 300 行代码(很多方法)。

【问题讨论】:

  • 您可以发布您的SinglyLinkedList 代码吗?看起来您正确地使用了ObjectOutputStream,但是如果不能看到正在序列化的代码,就很难判断序列化问题是什么。
  • 你是如何反序列化它的?如果可以,请发布任何代码
  • @BenLawry 我无法上传此代码,因为代码太大,但单链表有效 - 我有专门测试每种方法的测试类,它们工作正常 - 调试确定单链表的功能链表本身很好 - 问题在于保存它
  • @Arpit 请参阅上面的更新问题
  • @Lukeg101 SLL 是否是 JRE/JDK 的一部分并不重要。序列化对所有类的工作方式相同,无论这些类是内置的还是自定义的。通过实现Serializable,您将授予 JVM 遍历 SLL 的对象层次结构并将所有非瞬态实例变量写入磁盘的权限。如果您想要不同的行为,您必须正确覆盖 writeObject(ObjectOutputStream) 和 readObject(ObjectInputStream) 方法。这是 Java 语言的一个特性,无论你是否“使用标准 Java 类”都不会改变。

标签: java serialization io try-catch singly-linked-list


【解决方案1】:

您是否尝试在完成文件/对象的写入后在FileOutputStream 上调用close()?

【讨论】:

  • FileOutputStream 应该通过调用os.close() 来关闭,不是吗?
  • 有时调试的第一步是确保所有“当我这样做时应该发生”的东西都是明确的:)
  • 每次保存列表时 - 都会调用保存列表方法来执行此操作(见上文),并且该代码使用 close() 和 flush() 所以我很确定这不是问题。我也有密码方法可以将密码保存到另一个或多或少相同的文件(它保存一个字符串而不是单链表对象)虽然是个好建议
  • @mattb 我已经调试了单链表、客户文件和节点类——它们工作正常。问题在于主类的 IO,每次打开编程环境时,列表本身都是空的
【解决方案2】:

我已经解决了,我没有发布我的代码,而是尝试自己做。我发现列表类有一些静态方法 - 这些方法已更改为非静态方法,现在列表每次都按预期保存。 感谢您的帮助

【讨论】:

    猜你喜欢
    • 2016-07-17
    • 2012-10-26
    • 2020-04-20
    • 2019-09-20
    • 1970-01-01
    • 2017-06-16
    • 2019-06-03
    • 2011-10-17
    • 2013-05-20
    相关资源
    最近更新 更多