Input/Output Custom Serialization - hilfe bei Realisierung

GenerationLost

Mitglied
Hallo!

Ich möchte Java-Objekte mit Hilfe der Schnittstelle Serializable speichern und laden können. Das Problem ist, dass diese Objekte JavaFX Properties als Attribute besitzen, welche über Serializable eine Exception beim Schreiben werfen.

http://www.oracle.com/technetwork/articles/java/javaserial-1536170.html
Durch diesen Artikel habe ich erfahren, dass man aushebeln kann, indem man seine eigenen Lese- und Schreibemethoden in der zu serialierenden Klasse implementiert:
Java:
private void writeObject(ObjectOutputStream out) throws IOException
    {
        out.defaultWriteObject();
    }
 
    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
    {
        // our "pseudo-constructor"
        in.defaultReadObject();
        // now we are a "live" object again, so let's run rebuild and start
    }

http://stackoverflow.com/questions/7290777/java-custom-serialization
Über diesen Post habe ich so in etwa eine Ahnung bekommen, was in diesen Methoden passieren soll. So würde ich meine Werte als int speichern und beim Laden einfach in eine neue IntegerProperty umwandeln.
Dazu hat der InputStream z.B. eine readInt() Methode.

Was ich nicht ganz verstehe, wie sieht das mit der Reihenfolge aus? Ich kann ja nix x-beliebig nacheinander readInt() auf dem InputStream aufrufen. Es sind ja auch nicht nur Integer, sonder auch Doubles. Gibt es da eine Reihenfolge die ich einhalten muss? So einlesen wie geschrieben wurde, oder "von hinten" anfangen?

Ich habe leider keinerlei Ahnung davon, hoffe, ihr könnt mir weiterhelfen! 🙂

LG
GenerationLost
 
Zuletzt bearbeitet von einem Moderator:
Was ich nicht ganz verstehe, wie sieht das mit der Reihenfolge aus? Ich kann ja nix x-beliebig nacheinander readInt() auf dem InputStream aufrufen. Es sind ja auch nicht nur Integer, sonder auch Doubles. Gibt es da eine Reihenfolge die ich einhalten muss? So einlesen wie geschrieben wurde, oder "von hinten" anfangen?
Du solltest genauso lesen, wie du auch geschrieben hast
 
Danke, werde es mal ausprobieren!

Wie sieht das mit beliebig großen Listen aus? Die Liste als Objekt kann ich wohl auch nicht direkt einlesen, da deren Elemente ebenfalls Property-Attribute besitzen...
 
Mach die Listenelemente Serializable und überschreib deren de/serialisierung, dann kannst du auch die Liste als ganzes serialisieren
 
Geht dann auch sowas?

Code:
for (DoubleProperty d : times)
        {
            out.writeDouble(d.get());
        }

times ist eine ArrayList mit DoubleProperties.
 
Zuletzt bearbeitet von einem Moderator:
Ja, du musst dir dann nur auch speichern, wie viele Objekte du schreibst. Einfacher wird das vermutlich sein, das in eine List<Double> zu wandeln und die zu speichern
 
Also so?

Code:
ArrayList<Double> t = new ArrayList<Double>();
        for (DoubleProperty d : times)
        {
            t.add(d.get());
        }
        out.writeObject(t);
 
Zuletzt bearbeitet von einem Moderator:
Sorry für den Doppelpost, das sind jetzt meine gesamten beiden Lese und Schreibmethoden einer Klasse:

Java:
private void writeObject(ObjectOutputStream out) throws IOException
    {
        out.defaultWriteObject();
        out.writeInt(getTotalAnswers());
        out.writeInt(getTotalCorrectAnswers());
        out.writeInt(getTotalWrongAnswers());
        out.writeInt(getSkippedWords());
        out.writeInt(getSessionCountTotal());
        out.writeInt(getSessionCountNormal());
        out.writeInt(getSessionCountTimed());
        out.writeInt(getSessionCountTimedVocab());
        out.writeInt(getTimedOutSessions());
        out.writeInt(getTimedOutWords());
        out.writeInt(getCredits());
        out.writeDouble(getBestTime());
        out.writeDouble(getAvgTime());
        out.writeDouble(getPercentCorrect());
      
        ArrayList<Double> t = new ArrayList<Double>();
      
        for (DoubleProperty d : times)
        {
            t.add(d.get());
        }
      
        out.writeObject(t);
    }
     
    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
    {
         // our "pseudo-constructor"
         in.defaultReadObject();
         // now we are a "live" object again, so let's run rebuild and start
         this.totalAnswers = new SimpleIntegerProperty(in.readInt());
         this.totalCorrectAnswers = new SimpleIntegerProperty(in.readInt());
         this.totalWrongAnswers = new SimpleIntegerProperty(in.readInt());
         this.skippedWords = new SimpleIntegerProperty(in.readInt());
         this.sessionCountTotal = new SimpleIntegerProperty(in.readInt());
         this.sessionCountNormal = new SimpleIntegerProperty(in.readInt());
         this.sessionCountTimed = new SimpleIntegerProperty(in.readInt());
         this.sessionCountTimedVocab = new SimpleIntegerProperty(in.readInt());
         this.timedOutSessions = new SimpleIntegerProperty(in.readInt());
         this.timedOutWords = new SimpleIntegerProperty(in.readInt());
         this.credits = new SimpleIntegerProperty(in.readInt());
         this.bestTime  = new SimpleDoubleProperty(in.readDouble());
         this.avgTime = new SimpleDoubleProperty(in.readDouble());
         this.percentCorrect = new SimpleDoubleProperty(in.readDouble());
       
         ArrayList<Double> t = (ArrayList<Double>)in.readObject();

         for (Double d : t)
         {
             this.times.add(new SimpleDoubleProperty(d));
         }
    }

Wäre das dann so richtig?
 

Zurück
Oben