Question

Sometimes, I want to use an ObjectOutputStream to write something to a file or sending a little image over the network. But BufferedImage and many other classes don't implement java.io.Serializable and then the Stream cancels writing. Is there a way avoid that?

Thanks, Martijn

Was it helpful?

Solution

Only objects that support the java.io.Serializable interface can be written to streams.

-- ObjectOutputSteam docs

However, you could avoid all this by using one of the classes in javax.imageio. Specifically the ImageIO.write(RenderedImage, String, OutputStream) method, because BufferedImage implements RenderedImage. You can then read it back out with ImageIO.read(InputStream), which returns a BufferedImage.

You'll probably want a different OutputSteam type, though. In addition to the normal OutputStreams, there are several special ImageOutputStreams.

Edit: I missed this before: To get a list of valid strings for the middle argument, you can call ImageIO.getWriterFormatNames()

OTHER TIPS

No. That's like saying, "I want to display an object as text, but don't know anything about how to convert it into a string."

The entire purpose of Serializable is to say "I know how to be serialized to a stream!" - if we didn't need it, we wouldn't have it.

Now if you have an object which implements Serializable but contains something which itself doesn't implement Serializable, but which you could work out some way of serializing by hand, you could always customize the serialization of the container object yourself.

Basically ObjectOutputStream is designed for Java's serialization framework. If you don't want to use the serialization framework, don't use ObjectOutputStream. Images in particular are likely to have their own "native format" which ImageIO can deal with (as R. Bemrose noted).

One way to deal with unserializable objects is simply skip them. You can extends ObjectOutputStream and implement replaceObject method that checks if object is serializable.

public class MyOOS extends ObjectOutputStream {
    public MyOOS(OutputStream out) throws IOException {
        super(out);
        enableReplaceObject(true);
    }

    @Override
    protected Object replaceObject(Object obj) throws IOException {
        if ((obj instanceof Serializable))
            return obj;
        System.err.println("Skipping serialization of "+obj);
        return null;
    }
}

Write an ObjectOutputStream subclass, call enableReplaceObject, and then override replaceObject(Object). You probably also need a companion ObjectInputStream subclass does the same by overriding resolveObject(Object).

It may be an option for uou to use a different serialization mechanism. JBoss Serialization is a drop-in replacement for standard java.io serialization, although because the serialization format is different, both readers and writers need to use the same mechanism.

JBoss Serialization does not require classes to implement java.io.Serializable, however there's no guarantee that the objects will survive the process if they aren't explicitly Serializable.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top