从文件中读取序列化对象

时间:2010-05-26 13:50:26

标签: java serialization

我正在编写一个小程序(它是一个ImageJ插件,但问题不是专门与ImageJ相关)而且我有一些问题,很可能是因为我之前从未用Java编程...... < / p>

所以,我有一个矢量矢量,我试图将它保存到一个文件并阅读它。

变量定义为:

Vector <Vector <myROI> > ROIs = new Vector <Vector <myROI> >();

其中myROI是我之前定义的类。

现在,将矢量写入我使用的文件:

void saveROIs()
    {
    SaveDialog save = new SaveDialog("Save ROIs...", imp.getTitle(), ".xroi");
    String name = save.getFileName();
    if (name == null)
        return;
    String dir = save.getDirectory();

    try
        {
        FileOutputStream fos = new FileOutputStream(dir+name);
        ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(ROIs);
            oos.close();
        }
    catch (Exception e)
        {
        IJ.log(e.toString());
        }
    }

这正确地生成了一个二进制文件,其中包含(我想)对象ROIs

现在,我使用非常相似的代码来读取文件:

void loadROIs()
    {
    OpenDialog open = new OpenDialog("Load ROIs...", imp.getTitle(), ".xroi");

    String name = open.getFileName();
    if (name == null)
        return;
    String dir = open.getDirectory();

    try
        {
            FileInputStream fin = new FileInputStream(dir+name);
            ObjectInputStream ois = new ObjectInputStream(fin);
        ROIs = (Vector <Vector <myROI> >) ois.readObject(); // This gives error
            ois.close();
            }
    catch (Exception e)
        {
        IJ.log(e.toString());
        }
    }

但是这个功能不起作用。

首先,我收到警告:

 warning: [unchecked] unchecked cast found   : java.lang.Object
 required: java.util.Vector<java.util.Vector<myROI>>
            ROIs = (Vector <Vector <myROI> >) ois.readObject();
                                                        ^

我用Google搜索并看到我可以通过预先@SuppressWarnings("unchecked")来抑制,但这只会让事情变得更糟,因为我收到错误:

<identifier> expected
   ROIs = (Vector <Vector <myROI> >) ois.readObject();
        ^

在任何情况下,如果我省略@SuppressWarnings并忽略警告,则不会读取对象并抛出异常

java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: myROI

Google再次告诉我myROI需要implements Serializable。我尝试将implements Serializable添加到类定义中,但这还不够。在这种情况下,任何人都可以给我一些关于如何处理的提示吗?另外,如何摆脱类型转换警告?

2 个答案:

答案 0 :(得分:1)

myROI的每个属性都必须实现Serializable,或者必须是一个像int这样的简单数据类型。是这样吗?

答案 1 :(得分:1)

warning: [unchecked] unchecked cast found

这是无辜的,应该使用@SuppressWarnings("unchecked")注释确定。

<identifier> expected

这可能是由添加注释引起的。可能你把它添加到了错误的地方(应该在方法声明之前正确),或者你做了其他导致ROIs声明消失的事情。

java.io.NotSerializableException: myROI

这意味着由给定的完全限定类名标识的类不可序列化。期望它不可序列化,还有另一个严重的问题:该类不在一个包中。这不一定是当前问题的原因,但这可能会导致未来出现问题,因为无包装类对于包内的类是不可见的。

要使类可序列化,您需要让它implements Serializable并确保所有字段都可序列化。默认情况下,基元是可序列化的,String本身已经实现了它,因为您可以在its Javadoc中阅读。如果字段确实由于某种原因无法进行序列化,那么您需要声明transient并在必要时覆盖private void readObject()private void writeObject() accordingly这样无论如何都可以将不可序列化的对象写入/读取到蒸汽中。至此,您只需要以某种方式保存其状态,以便之后可以恢复完全相同的状态。

E.g。

public class SerializableObject implements Serializable {

    private transient UnserializableObject unserializableObject;

    private void writeObject(ObjectOutputStream oos) throws IOException {
        oos.defaultWriteObject();
        oos.writeObject(unserializableObject.getSerializableProperty());
        oos.writeObject(unserializableObject.getAnotherSerializableProperty());
        // ...
    }

    private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
        ois.defaultReadObject();
        unserializableObject = new UnserializableObject();
        unserializableObject.setSerializableProperty((SomeSerializableObject) ois.readObject());
        unserializableObject.setAnotherSerializableProperty((AnotherSerializableObject) ois.readObject());
        // ...
    }

}