简体   繁体   English

Java:使用不带序列化的ObjectOutputStream

[英]Java: Use ObjectOutputStream without serializable

Sometimes, I want to use an ObjectOutputStream to write something to a file or sending a little image over the network. 有时,我想使用ObjectOutputStream将某些内容写入文件或通过网络发送一些小图像。 But BufferedImage and many other classes don't implement java.io.Serializable and then the Stream cancels writing. 但是BufferedImage和许多其他类没有实现java.io.Serializable ,然后Stream取消了写入。 Is there a way avoid that? 有没有办法避免这种情况?

Thanks, Martijn 谢谢,Martijn

Only objects that support the java.io.Serializable interface can be written to streams. 只有支持java.io.Serializable接口的对象才能写入流。

-- ObjectOutputSteam docs - ObjectOutputSteam docs

However, you could avoid all this by using one of the classes in javax.imageio . 但是,您可以通过使用javax.imageio一个类来避免所有这些。 Specifically the ImageIO.write(RenderedImage, String, OutputStream) method, because BufferedImage implements RenderedImage . 特别是ImageIO.write(RenderedImage, String, OutputStream)方法,因为BufferedImage实现了RenderedImage You can then read it back out with ImageIO.read(InputStream) , which returns a BufferedImage . 然后,您可以使用ImageIO.read(InputStream)将其读回,该函数返回BufferedImage

You'll probably want a different OutputSteam type, though. 但是,您可能需要不同的OutputSteam类型。 In addition to the normal OutputStream s, there are several special ImageOutputStream s. 除了普通的OutputStream ,还有几个特殊的ImageOutputStream

Edit: I missed this before: To get a list of valid strings for the middle argument, you can call ImageIO.getWriterFormatNames() 编辑:之前我错过了:要获取中间参数的有效字符串列表,可以调用ImageIO.getWriterFormatNames()

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!" Serializable的全部目的是说“我知道如何序列化为流!” - 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. 现在,如果你有一个实现Serializable的对象但是包含一些本身实现Serializable ,但是你可以通过某种方式手工序列化,你总是可以自己定制容器对象的序列化。

Basically ObjectOutputStream is designed for Java's serialization framework. 基本上, ObjectOutputStream是为Java的序列化框架而设计的。 If you don't want to use the serialization framework, don't use ObjectOutputStream . 如果您不想使用序列化框架,请不要使用ObjectOutputStream Images in particular are likely to have their own "native format" which ImageIO can deal with (as R. Bemrose noted). 特别是图像可能有自己的“本机格式”, ImageIO可以处理(如R. Bemrose所说)。

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. 您可以扩展ObjectOutputStream并实现replaceObject方法,该方法检查对象是否可序列化。

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). 编写ObjectOutputStream子类,调用enableReplaceObject,然后重写replaceObject(Object)。 You probably also need a companion ObjectInputStream subclass does the same by overriding resolveObject(Object). 您可能还需要一个伴随的ObjectInputStream子类通过重写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是标准java.io序列化的直接替代品,但由于序列化格式不同,读者和编写者都需要使用相同的机制。

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. JBoss Serialization不需要类来实现java.io.Serializable ,但是如果它们不是显式的Serializable,则无法保证对象将在进程中存活。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM