【问题标题】:Java Serializable SavingJava 可序列化保存
【发布时间】:2012-07-13 17:05:04
【问题描述】:

嗯,我有这个课程用于我正在制作的游戏,我正在尝试保存 ArrayList 注释。当我注销时,它会正确打印大小,例如,如果我有 5 个笔记,当我注销时 notes.getSize() 将为 5,但当我登录时,它会重置为空。为什么没有保存笔记?

public class Notes implements Serializable {

    private static final long serialVersionUID = -4947870743226160329L;
    private ArrayList<Note> notes = new ArrayList<Note>(30);

    public class Note implements Serializable {

        private static final long serialVersionUID = -4589885080580317958L;

        private int color = 0;
        private String text = "";

        public Note(int color, String text) {
            this.setColor(color);
            this.setText(text);
        }

        public void setText(String text) {
            this.text = text;
        }

        public String getText() {
            return text;
        }

        public void setColor(int color) {
            this.color = color;
        }

        public int getColor() {
            return color;
        }
    }

    private transient Player player;

    public Notes(Player p) {
        this.player = p;
    }

    public void addNote(String text) {
        System.out.println("Note Text: "+text);
        if (text.length() > 50) {
            player.getPackets().sendGameMessage("You can only enter notes up to 50 characters!");
            return;
        }
        if (notes.size() < 30) {
            notes.add(new Note(0, text));
        } else {
            player.getPackets().sendGameMessage("You cannot add more then 30 notes!");
            return;
        }
        int NoteId = notes.size() - 1;
        player.getPackets().sendConfig(1439, NoteId);
        player.getTemporaryAttributtes().put("selectedNote", NoteId);
        refreshNotes(false);
    }

    public void addNote(String text, int color) {
        notes.add(new Note(color, text));
    }

    public void loadNotes() {
        player.getPackets().sendIComponentSettings(34, 9, 0, 30, 2621470);
        player.getPackets().sendHideIComponent(34, 3, false);
        player.getPackets().sendHideIComponent(34, 44, false);
        player.getPackets().sendIComponentText(34, 13, "Loading notes<br>Please wait...");
        player.getPackets().sendConfig(1439, -1);
        refreshNotes(true);
    }

    public void refreshNotes(boolean sendStartConfigs) {
        for (int i = 0; i < 30; i++) {
            player.getPackets().sendGlobalString(149 + i, i < notes.size() ? notes.get(i).getText() : "");
        }
        if (sendStartConfigs) {
            for (int i = 1430; i < 1450; i++)
                player.getPackets().sendConfig(i, i);
        }
        player.getPackets().sendConfig(1440, getFirstTotalColorValue());
        player.getPackets().sendConfig(1441, getSecondTotalColorValue());
    }


    public int intColorValue(int color, int noteId) {
        return (int) (Math.pow(4, noteId) * color);
    }

    public int getFirstTotalColorValue() {
        int Color = 0;
        for (int i = 0; i < 15; i++) {
            if (notes.size() > i)
                Color += intColorValue(notes.get(i).getColor(), i);
        }
        return Color;
    }

    public int getSecondTotalColorValue() {
        int color = 0;
        for (int i = 0; i < 15; i++) {
            if (notes.size() > (i + 16))
                color += intColorValue(notes.get(i + 16).getColor(), i);
        }
        return color;
    }

    public void deleteSelectedNote() {
        if ((int)player.getTemporaryAttributtes().get("selectedNote") > -1) {
            int slot = (int) player.getTemporaryAttributtes().get("selectedNote");
            notes.remove(slot);
            player.getTemporaryAttributtes().put("selectedNote", -1);
            player.getPackets().sendConfig(1439, -1);
            refreshNotes(false);
        }
    }

    public void clear() {
        notes.clear();
        refreshNotes(false);
    }

    public void editNote(String string, int index) {
        notes.get(index).setText(string);
        refreshNotes(false);
    }

    public void setColor(int color, int index) {
        notes.get(index).setColor(color);
        refreshNotes(false);
    }

    public void deleteNote(int slot) {
        notes.remove(slot);
        refreshNotes(false);
    }

    public void setNotes(ArrayList<Note> setNotes) {
        notes = setNotes;
        refreshNotes(false);
    }

}

这是我管理保存/加载的类

公共类 SerializableFilesManager {

private static final String PATH = "data/characters/";
private static final String BACKUP_PATH = "data/charactersBackup/";

public synchronized static final boolean containsPlayer(String username) {
    return new File(PATH + username + ".p").exists();
}

public synchronized static Player loadPlayer(String username) {
    try {
        return (Player) loadSerializedFile(new File(PATH + username + ".p"));
    } catch (Throwable e) {
        Logger.handle(e);
    }
    try {
        Logger.log("SerializableFilesManager", "Recovering account: "
                + username);
        return (Player) loadSerializedFile(new File(BACKUP_PATH + username
                + ".p"));
    } catch (Throwable e) {
        Logger.handle(e);
    }
    return null;
}

public static boolean createBackup(String username) {
    try {
        Utils.copyFile(new File(PATH + username + ".p"), new File(
                BACKUP_PATH + username + ".p"));
        return true;
    } catch (Throwable e) {
        Logger.handle(e);
        return false;
    }
}

public synchronized static void savePlayer(Player player) {
    try {
        storeSerializableClass(player, new File(PATH + player.getUsername()
                + ".p"));
    } catch (ConcurrentModificationException e) {
        //happens because saving and logging out same time
    } catch (Throwable e) {
        Logger.handle(e);
    }
}

public static final Object loadSerializedFile(File f) throws IOException,
        ClassNotFoundException {
    if (!f.exists())
        return null;
    ObjectInputStream in = new ObjectInputStream(new FileInputStream(f));
    Object object = in.readObject();
    in.close();
    return object;
}

public static final void storeSerializableClass(Serializable o, File f)
        throws IOException {

    ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(f));
    out.writeObject(o);
    out.close();
}

private SerializableFilesManager() {

}

}

【问题讨论】:

  • 您实现了Serializable,但我没有看到您在任何地方都在执行 i/o。您是否创建了ObjectOutputStream 并在任何地方调用writeObject()
  • 忘记添加该类,现在才添加。

标签: java serializable


【解决方案1】:
  1. 不要将播放器标记为瞬态,因为您正在保存它,瞬态将阻止如果从 被保存,并在反序列化时将播放器带到 null 的默认值

  2. 您是否使播放器类可序列化?

  3. 整个对象图被序列化或没有...瞬态的目的是使特定成员在序列化过程中被忽略,所以这样,序列化的过程就很顺利了。

  4. 例如,假设在一个游戏中,我们想要保留玩家的进度和该会话的游戏小时数,而不是开始和结束时间。所以开始和结束时间可以是瞬态的。

【讨论】:

  • 是的,Player 类是可序列化的,但我是否需要声明这两件事才能使其保存?私人笔记笔记类;和私人笔记;
  • 我认为Notes 是Outer 类,使其变量可以访问自身和Inner 类(Note)给玩家...
【解决方案2】:

您应该将 ArrayList 保存为:

 FileOutputStream fos = null;
    ObjectOutputStream out = null;
    try {
        fos = new FileOutputStream("filename",false);
        out = new ObjectOutputStream(fos);
        out.writeObject(notes);
        out.close();
        System.out.println("Object Persisted");
    } catch (IOException ex) {
        ex.printStackTrace();
    }

当你打开你的项目时,导入你的Arraylist:

    FileInputStream fos;
    try {
            fos = new FileInputStream("filename");
             ObjectInputStream oos = new ObjectInputStream(fos);
             notes=(ArrayList) oos.readObject();
                fos.close();
            {
          catch {
        }

【讨论】:

    【解决方案3】:

    那是因为您的Playertransient...我已经尝试在其他示例中演示您的逻辑...当Player 设置为private 时,序列化成功并且所有数据都已加载回来。否则,当瞬态时,播放器引用为null,它仅加载其他序列化字段,如int。当class 中只有一个transient Player 作为字段时,会出现NullPointerException,但ArrayListsize &gt; 0

    【讨论】:

      猜你喜欢
      • 2013-07-23
      • 2015-04-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-28
      • 1970-01-01
      • 2013-01-20
      • 1970-01-01
      相关资源
      最近更新 更多