0

I have an object BatchState that has pointers to a number of pieces of data, including a BufferedImage. I need to serialize the object.

Here's a simplified version of my BufferedImage:

public class BatchState implements Serializable{
    private int anInt;
    //A bunch of other primitives and objects
    //...
    private transient Image image; //This is the BufferedImage

    //Constructors, methods, and so forth
    //...
}

I have made the Image transient so that I can then write it to a different file using ImageIO.

I am trying to serialize the object using this code:

public void saveState(){
    ObjectOutputStream oos = null;
    FileOutputStream fout = null;
    try{
        fout = new FileOutputStream("data/saved/"+Client.getUser()+".sav", true);
        oos = new ObjectOutputStream(fout);
        oos.writeObject(batchState);
        oos.close();
    } catch (Exception e) {
        e.printStackTrace();
    } 
}

However, any time I call this method, my program throws the follow exception:

java.io.NotSerializableException: java.awt.image.BufferedImage

This in spite of the fact that the BufferedImage is transient.

I am looking for one of two solutions:

  1. Find a way to serialize the BufferedImage along with the rest of the data, or
  2. Find a way to serialize the BatchState to one file and then write the BufferedImage to a separate file.

Either solution is fine.

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Benjamin
  • 1,372
  • 2
  • 12
  • 20
  • Your code runs fine for me (Initializing the image and changing the filename, of course). Are you sure you don't have another Image variable which you forgot to mark as transient? – Vitruvie Dec 11 '13 at 06:13
  • Your code doesn't throw that exception. You must be running an older version without the `transient` keyword on `image.` – user207421 Dec 11 '13 at 06:28
  • For better help sooner, post an [SSCCE](http://sscce.org/). BTW - A good way to store a bunch of disparate information is in a Zip file. Each resource can have its own 'path' within the Zip, and they are easy to access. – Andrew Thompson Dec 11 '13 at 06:30

2 Answers2

3

You could write yourself a custom writeObject() method that calls first out.defaultWriteObject() and then ImageIO.write(image, "jpeg", out) (or whatever format you prefer, and similarly a custom readObject() method that does the converse. See the Object Serialization Specification for the correct signatures of these methods.

user207421
  • 305,947
  • 44
  • 307
  • 483
0

Solved. It involved some other data that I didn't include in the code that I showed above. Your guys' comments helped me realize what the problem was, though.

It turns out that the BufferedImage there visible wasn't the problem at all. I had a pointer to another object which ALSO contained a BufferedImage, and it was that other BufferedImage (nested in another object) that was causing the OutputStream to throw its exception.

Moral of the story: ObjectOutputStream will serialize even deeply nested objects.

Benjamin
  • 1,372
  • 2
  • 12
  • 20