2
\$\begingroup\$

I have read a lot about serialization and I cannot figure out how I am able to serialize then deserialize multiple objects. I am very much a newb to Java, so please bear with me.

My code currently works, but my logic is flawed. I have an object called "club", which contains several fields to be serialized e.g teamname. I have used case statements with a switch, so that I can serialize more than one object, but I ended up re-trying my try/catch block and streams to get it to work.

Both objects can be independently written to a file, but I am unclear of the syntax to use, to ensure I can implement the following pseudocode.

if teamName = club1 and player would like to save the game serialize club1 then de-serialize club1, if player selected load game.

Finally, could someone point me in the right direction of writing a game "state" to a file, rather than just pre-defined fields that I have declare as constants.

Snippets of my code are as follows :

switch (option) {

    case 1:
    chooseTeam(clubName);
    exit = true;    
    break;

    case 2: 
    Serialize saveclub1 = new Serialize();
    saveclub1.Serialize();
    exit = true;    
    break;

    case 3:
        DeSerialize load = new DeSerialize();
        load.DeSerialize(clubName);
        exit = true;
    break;

    case 4:
    credits();  
    exit = true;
    break;

    case 5:
    exit = true;    
    System.out.println("Goodbye!");
    break;

    case 6:

    Serialize saveclub2 = new Serialize();
    saveclub2.Serialize();
    ClubInfo club2 = new ClubInfo();
      club2.teamName = "Aston Villa";
      club2.stadium = "Villa Park";
      club2.division = "Premier League";
      club2.SSN = 11122333;
      club2.stadiumCapacity = 40000;
    try
        {
         FileOutputStream fileOut =
         new FileOutputStream("/home/cg/root/club.ser");
         ObjectOutputStream out = new ObjectOutputStream(fileOut);
     out.writeObject(club2);
     out.close();
         fileOut.close();


      //System.out.printf("Serialized data is saved in C:/tmp/club.ser");
      }catch(IOException i)
      {
          i.printStackTrace();
      }
     exit = true;
        break; 

public void DeSerialize(String[] clubName)
   {
      ClubInfo club = null;

      try
      {
         FileInputStream fileIn = new FileInputStream("/home/cg/root/club.ser");
         ObjectInputStream in = new ObjectInputStream(fileIn);
         club = (ClubInfo) in.readObject();

         in.close();
         fileIn.close();

      }catch(IOException i)
      {
         i.printStackTrace();
         return;
      }catch(ClassNotFoundException c)
      {
         System.out.println("Club class not found");
         c.printStackTrace();
         return;
      }

public void Serialize()
   {


      ClubInfo club = new ClubInfo();
      club.teamName = "Arsenal";
      club.stadium = "Emirates";
      club.division = "Premier League";
      club.SSN = 11122333;
      club.stadiumCapacity = 60000;



      try
      {
         FileOutputStream fileOut =
         new FileOutputStream("/home/cg/root/club.ser");
         ObjectOutputStream out = new ObjectOutputStream(fileOut);
     out.writeObject(club);

         out.close();
         fileOut.close();


      System.out.printf("Serialized data is saved in C:/tmp/club.ser");
      }catch(IOException i)
      {
          i.printStackTrace();
      }

   }
}

public class ClubInfo implements java.io.Serializable{


   public String teamName;
   public String stadium;
   public String division;
   public transient int SSN;
   public int stadiumCapacity;

} // end ClubInfo class
\$\endgroup\$
  • \$\begingroup\$ Have you by any chance reviewed and implemented the suggested improvements in your earlier question? :) \$\endgroup\$ – h.j.k. Oct 8 '15 at 11:58
  • \$\begingroup\$ Absolutely, I haven't included all of my code, I am frequently using loops, in the interests of code re-use. I am looking into using serializeVersionUID. But I don't understand, and cannot locate via google, Serialization is such a massive topic, it is hard to refine my search. I am very much a newb, any suggestions would be much appreciated. \$\endgroup\$ – Darren Estcourt Oct 8 '15 at 12:01
  • \$\begingroup\$ There's a link in my answer regarding that... \$\endgroup\$ – h.j.k. Oct 8 '15 at 12:03
  • \$\begingroup\$ To be more specific, I am aware that I should just be able to call the writeObject and readObject methods, multiple times. But I can't find examples of the syntax used to call these methods. The only way I could call these methods, from my basic understanding, is via a switch statement. \$\endgroup\$ – Darren Estcourt Oct 8 '15 at 12:17
  • \$\begingroup\$ I think what you have is more or less correct. Are you just confused about how to save and load multiple clubs instead of just one? \$\endgroup\$ – duraz0rz Oct 8 '15 at 15:20
1
\$\begingroup\$

Based on the comments, I think you're confused about actually saving/loading distinct ClubInfo objects. You can call writeObject and readObject multiple times, but you need to store those ClubInfo objects in separate files if you want to persist them.

What you could do is add a ClubInfo parameter to your Serialize method, then name the file you save based on the clubName. By doing this, you don't tie down your serialize method to one instance of ClubInfo...you can pass in any ClubInfo object and it will save it to a different output file:

public void Serialize(ClubInfo club) {

  String fileName = club.teamName + ".ser";

  try {
    FileOutputStream fileOut = new FileOutputStream("/home/cg/root/" + fileName);
    ObjectOutputStream out = new ObjectOutputStream(fileOut);

    out.writeObject(club);
    out.close();
    fileOut.close();

    System.out.println("Serialized data is saved in C:/tmp/club.ser");

    } catch(IOException i) {
        i.printStackTrace();
    }
  }
}

This is close to your original code. A few things I would change:

  • Assuming you're using Java 7 or newer, use the try-with-resources feature so you don't explicitly have to call close() on your streams.
  • I would have the thread throw the IOException that's required instead of handling it inside the method itself. It makes the method cleaner and you can handle the exception in different ways, depending on where and how you call it.

Here's how it looks afterwards:

public void Serialize(ClubInfo club) throws IOException {

  String fileName = "/home/cg/root/" + club.teamName + ".ser";

  try (FileOutputStream fileOut = new FileOutputStream(fileName);
       ObjectOutputStream out = ObjectOutputStream out = new ObjectOutputStream(fileOut)) {
    out.writeObject(club);
    System.out.println("Serialized data is saved in C:/tmp/club.ser");
    } 
  }
}

And to call it:

case 2: 
    Serialize saveclub1 = new Serialize();
    try {
      saveclub1.Serialize(club1);
    } catch(IOException e) {
      System.out.println("Error saving club!");
    }

    exit = true;    
    break;

You can do the same-ish thing with Deserialize. I would pass in the teamName I want to search for, get a list of files from the directory I am persisting the objects to and look for the file name that contains the team name. Then call readObject and return it from the Deserialize method. The method signature would look like this:

public ClubInfo Deserialize(String teamName)

Then your method isn't tied to the single club file.

This should also lead you in the direction you should take in saving the game state. I'll leave that to you to figure the guts out, but that should get you in the right direction!

\$\endgroup\$
  • \$\begingroup\$ Thanks so much for that, I have plenty to ponder over :) \$\endgroup\$ – Darren Estcourt Oct 8 '15 at 16:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.