为了账号安全,请及时绑定邮箱和手机立即绑定

正确存储和管理(反)序列化的对象以及反序列化后如何使用它们

正确存储和管理(反)序列化的对象以及反序列化后如何使用它们

一只名叫tom的猫 2022-11-02 15:19:19
我想使用(反)序列化使用具有保存/加载功能的类中的数据将多个对象加载和渲染到游戏世界,但我无法弄清楚如何正确地将它们重新引入程序,因为它们包含必要的瞬态对象渲染/显示它们。我第一次运行我的程序时,它会尝试从不存在的名为“Data.txt”的 txt 文件中加载数据。该程序创建一个新的 Data.txt 文件,向其中添加一个名为“campfire”的 Campfire 对象并保存它。只要程序运行,它就会被渲染到屏幕上(这部分工作正常)。关闭程序并重新启动它应该检查文件后,找到它并使用先前保存/序列化的篝火对象加载 ArrayList '数据'。然后它向它添加另一个相同类型的 Object 并渲染它们。这部分在我的 Campfire 类的渲染方法中引发 NullPointerException。这是主类:public class MainClass extends ApplicationAdapter{public static SpriteBatch batch;    private Data data;private Campfire campfire;@Overridepublic void create () {    batch = new SpriteBatch();    data = new Data();    data.load();    campfire = new Campfire();    data.addCampfire(campfire);    System.out.println(data.getSize());    data.save();}@Overridepublic void render () {    Gdx.gl.glClearColor(0, 0, 0, 1);    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);    batch.begin();        data.render(batch);    batch.end();}加载所有文件的类:public class Data {private String filename;private ArrayList<Campfire> data; public Data() {    data = new ArrayList<Campfire>();     filename = "Data.txt";  } public void save(){     try {           FileOutputStream file = new FileOutputStream (filename);          ObjectOutputStream out = new ObjectOutputStream (file);                out.writeObject(data);          out.close();          file.close();           }catch (IOException e) {e.printStackTrace();}  }public void load() {     try {                                           FileInputStream file = new FileInputStream (filename);          ObjectInputStream in = new ObjectInputStream(file);          data = (ArrayList<Campfire>)in.readObject();           in.close();          file.close();       } 原因是纹理“img”不存在,因为我需要对它使用瞬态关键字,因此它不会被保存/加载到数据文件中/从数据文件中加载。我需要一种不同的方法来根据我从中加载的数组列表创建对象。我无法使用 arrayList 中的对象,因为它们无法被渲染(transient 关键字必须分配给 Texture() 对象 - 它不可序列化)。我看过很多教程并阅读了大量关于这个主题的文章,但我找不到一篇提到我如何重新引入对象以便我可以利用它的函数,这些函数依赖于它的不可(反)序列化部分。所以这是我的问题:有没有比我的尝试更好的方法(再次创建对象然后为其分配反序列化的值?我不知道如何在反序列化过程之后正确加载和使用“数据”ArrayList,我是感谢有关如何将它们重新引入该计划的每条建议。
查看完整描述

1 回答

?
慕沐林林

TA贡献2016条经验 获得超9个赞

我建议不要为此使用 java 序列化。它在序列化格式的大小方面可能具有优势,但根据我的经验,使用它有点痛苦。您遇到了这种痛苦,因为您无法序列化该Texture对象,因为它不是Serializable. 您通过将其标记为瞬态来避免该问题,这是一个错误。可能有一些解决方法可以处理您不拥有的对象 - 注册一些处理程序,但是我不知道细节,因为我避免了它。

相反,请选择像 json 这样友好的格式。这意味着您的序列化数据文件会更大一些,但是,您可以打开它并阅读它并查看您保存的内容。

而且... libgdx 附带了一些工具。在此处查看他们的 wiki 页面以了解使用情况

还有其他选择——比如谷歌的 gson 库,但为什么不坚持使用 libgdx 的工具——我发现它们非常可靠。

只是一个额外的警告 - 如果您在 Android 中使用某种代码混淆/最小化工具,您需要将其配置为不重命名您序列化的任何对象,因为它确实依赖于包和对象名称进行反序列化。如果您保存游戏状态,也需要注意 - 然后更改对象的名称/包,然后尝试加载该游戏状态。


查看完整回答
反对 回复 2022-11-02
  • 1 回答
  • 0 关注
  • 86 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信