【问题标题】:Java serialisation of complicated and HUGE data structures复杂庞大数据结构的Java序列化
【发布时间】:2011-07-26 02:20:43
【问题描述】:

我有一个模型,需要以某种方式将其写入磁盘,然后再读取(制作一个简单的 Java 2D 游戏)。现在,有一个对 Player 的引用,其中包含对块和实体的大量引用。在我的项目中有大量的实体和块,我真的不想写一个 toString()/encode() 然后 fromString()/decode()... 这个项目无论如何都过期了,在这里它的 4:早上 5 点:p.

那么,在这种情况下,人类会做什么?爬到这里询问序列化是做什么的,以及它是否会立即起作用。我认为它必须在第一次运行时就可以工作,可悲的是,实验者没有太多空间。

以下情况需要全部写入磁盘。可以使用单个 serialize() 函数:o ?

现在,想象一下这个虚构的类(实际上我有 5800 行 java 代码和大量混合数据,这很痛苦)(没有函数)(我的脑海中浮现):

class InventorySlot { Object[] list; Class type; int quantity; }
class Inventory { InventorySlot[] slots; }

class Player { int hp; Inventory inv,palette; double x,y; }

enum Block { air, stone, cobble, dirt, etc; }
class Entity { double x,y,dir,speed,h,w; /*AND CUSTOMS! (derivers)*/ }   
class EntitySpriteAnimationPuf { Particle[] parts; final double friction, dir, dirnoise; Color color; } // final vars!
class World
{
    List<Chunk> chunks; // have an infinite map. each chunk is 64x64 Blocks.
    Entity[65535] entities; // I have a lot of entites, both types and later their instances.
}
class Model // target class to be entirely written down
{
    Player p;
    WindowManager wm; // Yes, i have my own GUI. Yes, it looks wonderful. Yes its got a lot of data... Yes, ouch.
    World w; // got this manually written down.
    Vector<String> terminal; // Dont want this to be serialized...
    boolean guiactive, pause;
    // And a few more...
}
// AND A LOT MORE. MORE. MORE. MORE. MORE. MORE. MORE. MORE. MORE. MORE. MORE. MORE. MORE.

【问题讨论】:

  • 所有对象都符合 bean 模式吗?如果他们这样做了,您可以使用 Jackson 序列化/反序列化为 JSON,它会这样做没有注释并且没有嵌套序列化函数。
  • 我没有任何外部库。纯java。没有豆子。这是一个无网络连接的本地桌面应用程序/游戏,没有任何 grpahical 加速或其他任何东西。这是我的第一个 java 项目,虽然我非常擅长 C/C++
  • 遵循 bean 模式意味着您的所有数据字段(至少您想要序列化的那些)都有 getter 和 setter,对于某些字段 foo 您将拥有 T getFoo()void setFoo(T val) 用于某些类型 T。然后你需要一个外部库来进行序列化。
  • 没有。大多数甚至不遵循标准。 int hp; int hp(){return hp;} void hp(int hp){this.hp=hp;}... :P (/me C 程序员)
  • 我怀疑你找不到免费的解决方案,考虑把所有东西都变成一个 bean(大多数 IDE 会为你生成 getter 和 setter,Eclipse 肯定会),然后使用能够序列化 bean 和嵌套 bean,例如 Jackson。

标签: java serialization


【解决方案1】:

这是加载/保存 java 对象需要做的事情(忽略异常处理)

确保所有类都实现了 Serializable 接口

要知道的是,如果您更改了任何序列化类,那么

你的“反序列化”很可能会失败

public void load() {
    FileInputStream filein = new FileInputStream("data");
    ObjectInputStream in = new ObjectInputStream(filein);
    Model model = (Model) in.readObject();
    in.close();
}

public void save() {
    ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("data"));
    out.writeObject(model);
    out.close();
}

【讨论】:

  • 如果我只序列化一次模型,写入磁盘,忘记整个世界的所有麻烦及其可怜的玩家和实体等就足够了吗? (这是我真正的简单问题
  • “忘掉全世界所有的烦恼”是什么意思?
  • @imacacke 是的,您只序列化图形层次结构顶部的对象,然后所有可访问的对象也被序列化!
【解决方案2】:

如果您不想编写自己的序列化代码,那么kryo 是Java Serializable 的更好替代方案。尤其是在考虑性能和序列化大小的情况下(听起来很适合您)。

是的,您所要做的就是用 kryo 注册您的每个模型类,然后将其交给对象图以进行序列化。

如果您需要比自动序列化程序更高效(这仍然比 Java 的效率高得多),您还可以为特定类添加单独的序列化程序。

它也(在某种程度上)更能抵抗类和 JVM 版本的变化; Serializable 在这方面非常脆弱。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-17
    • 1970-01-01
    相关资源
    最近更新 更多