将对象保存到文件

3

我需要将一个对象及其所有属性保存到文件中。

我不允许更改对象的类。此对象无法序列化。那么我该如何将此对象保存到文件中以备后用?


很难为我解释。 我只是有一个对象并需要将其保存到磁盘。 - xDarcade
1
点赞了毫无意义的未经解释的踩。这些评论的质量令人沮丧。我从来不明白为什么人们会对他们不理解的事情发表评论,或者当他们不知道自己在说什么时。 - user207421
@StefanoSanfillipo 唯一必要的链接是我认为在一个评论中同时提到它们比分开两条更合适。也许你可以停止吹毛求疵,学习一下本主题的相关知识。否则你在这里出现将会变得难以解释。 - user207421
@EJP 好的,我想我只是过于草率地得出了结论,没有考虑到所有(与Serializable无关)的可能性。现在我看到了答案,我会删除第一条评论。 - Stefano Sanfilippo
5个回答

2
如果对象符合Java Beans规范(除了Serializable要求),您可以使用java.beans.XMLEncoder。

OP明确表示他/她的对象无法序列化。JavaBeans规范要求在§5.5中,“所有bean必须支持序列化或外部化”,因此他/她的对象不符合Java Beans规范。 - Stefano Sanfilippo
@StefanoSanfillipo 尽管如此,这个编码器并没有Serializable的要求,你可以通过查找或自己尝试来发现这一点,而不是对你一无所知的事情进行荒唐的声明。 - user207421
我只是想通过留言来帮助您使这个答案更准确。如果您认为这是吹毛求疵,我很抱歉。我承认我没有调查过这种方法,但我看到了一个不一致之处,觉得有必要通知您。 - Stefano Sanfilippo

2
如果您想避免使用默认的Java序列化,有两个选项。一是编写自定义的writer和reader,在其中手动将值写入文件。另一种是使用JSON或XML序列化库(不使用Java序列化)。前者需要大量工作,不值得。后者可以使用类似于Jackson的库来实现。请注意保留HTML标记。

0

它并不适用于所有情况,但您可以使用ObjectOutputStream

假设您的类Foo不可序列化。创建另一个FooState来包含Foo实例状态。

public class Foo {
    private String string;
    private Date date;
    /* ... */
}

public class FooState {
    private String string;
    private Date date;

    public FooState(Foo foo) {
        this.string = foo.getString();
        this.date = foo.getDate();
        /* ... */
    }

    private Object readResolve() throws ObjectStreamException {
        return new Foo(string, date, ...);
    }
}

然后子类化ObjectOutputStream。使用这个类,可以在序列化和反序列化时透明地替换非可序列化对象为可序列化对象。

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

    protected FooObjOutputStream() throws IOException, SecurityException {
        super();
        enableReplaceObject(true);
    }

    @Override
    protected Object replaceObject(Object obj) throws IOException {
        if (obj instanceof Foo) {
            return new FooState((Foo) obj);
        } else {
            return super.replaceObject(obj);
        }
    }
}

然后进行序列化/反序列化

private static byte[] serialize(Object o) throws Exception {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    FooObjOutputStream oos = new FooObjOutputStream(baos); // Magically handling Foo objects
    oos.writeObject(o);
    oos.flush();
    oos.close();
    return baos.toByteArray();
}

public static Object deserialize(byte[] bytes) throws IOException, ClassNotFoundException {
    ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
    ObjectInputStream ois = new ObjectInputStream(bais);
    Object o = ois.readObject();
    bais.close();
    return o;
}

0
将对象保存到文件中意味着保存其状态和字段。您可以尝试使用java.io.DataOutputStream,它具有保存任何原始类型和字符串所需的所有方法。稍后,您可以通过使用java.io.DataInputStream从文件中读取其字段来重新创建对象。这取决于对象类,但即使对象不是一个bean,也就是说它不允许读取/设置其字段,您仍然可以尝试使用反射来访问其字段。

0

如果允许使用第三方库,您可以尝试使用类似于 Kryo 的序列化库。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接