【问题标题】:ClassNotFoundException in reading object from GZipped file从 GZipped 文件中读取对象时出现 ClassNotFoundException
【发布时间】:2016-10-31 18:19:25
【问题描述】:

*.gz 文件是在我正在使用的包的先前版本下创建的(它具有类 tratz.semantics.ClassificationBundle)。在当前版本中,该类被命名为 miacp.semantics.ClassificationBundle。两者的成员相同。有什么方法可以让早期版本在后期版本中可读吗?基本的读取功能是

ClassificationBundle bundle = (ClassificationBundle) ois.readObject();

我有较早的版本,所以我可以读取那个版本的文件。但是,我将如何创建一个可以在新版本中读取的新文件?

【问题讨论】:

  • 你被咬过一次:我会停止使用 Java 序列化进行长期存储。使用更易读、可定制、可移植的机制,例如 JSON 或 XML,任何程序、任何库版本、使用任何语言都可以读取。并且任何文本编辑器都可以进行编辑。
  • 这些文件相当大(50MB 到 90MB);我正在加载其中的五个。数据结构相当复杂。
  • 如果miacp 包与tratz 包不冲突,您应该能够将两个包放在同一个类路径中。编写一个实用程序,将tratz.semantics.ClassificationBundle 对象的内容复制到新的miacp.semantics.ClassificationBundle 对象中。

标签: java serialization gzipinputstream


【解决方案1】:

Java 二进制序列化对任何类型的重构都非常不利。不幸的是,tratz.semantics.ClassificationBundle 永远不能反序列化为miacp.semantics.ClassificationBundle

JSON 或 XML 序列化是此类问题的常见解决方案。或者,您可以创建自定义存储格式。或者您可以简单地存储原始/简单数据值,然后加载这些值而不是加载自定义对象(int/long/double/String/...等)。

【讨论】:

    【解决方案2】:

    使用readResolve() 方法将tratz.semantics.ClassificationBundle 类放回去,这将创建您的新对象。当所有序列化内容以新格式(作为新类)反序列化后,您将能够删除这个旧存根。

    【讨论】:

      【解决方案3】:

      我成功地遵循了 flakes 的建议,将两个包都放在了类路径中。希望描述细节很有用。使用 Netbeans,我创建了另一个到 tratz 的源路径,并添加了一个子文件夹并将原始 ClassificationBundle 类复制到该文件夹​​。 Netbeans 告诉我需要导入的其他包,因此我也可以将它们复制到相应的子文件夹中。然后我回到上面引用的原始代码来读取对象。我继续为其他课程获得ClassNotFoundException。这导致需要复制其他类。最终,我复制了 57 个类,并且能够成功读取 GZipped 文件。下一步是编写实用程序来复制内容(要简单得多,但考虑到数据结构的复杂性,仍然存在一些困难)。

      谢谢

      【讨论】:

        猜你喜欢
        • 2018-05-20
        • 2012-12-17
        • 1970-01-01
        • 1970-01-01
        • 2013-07-07
        • 1970-01-01
        • 2020-10-28
        • 2021-03-11
        相关资源
        最近更新 更多