【发布时间】: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