【发布时间】:2018-05-17 09:06:36
【问题描述】:
当我尝试反序列化 java.math.BigDecimal 时出现以下错误:
java.io.InvalidClassException: java.math.BigDecimal; local class incompatible:
stream classdesc serialVersionUID = 6108874887139371087,
local class serialVersionUID = 6108874887143696463
我知道如果你实现 Serializable 接口而不定义serialVersionUID,就会发生这个错误,但是我的类确实定义了它:
public class Foo implements java.io.Serializable {
private static final long serialVersionUID = -2280646288949622888L;
private int a;
private long b;
private java.lang.String c;
private java.math.BigDecimal d;
}
此外,它还专门抱怨 BigDecimal,它是 JDK 的一部分,如果我信任 Eclipse 的反编译器,它还定义了 serialVersionUID:
private static final long serialVersionUID = 6108874887143696463L;
我读过in some cases (such as using GWT),你可以有不同的 BigDecimal 类实现,具有不同的串行版本,这将避免正确的反序列化。它也可能发生在不同机器上具有相同类的不同版本。但就我而言,我在同一台机器上,在同一个 JBoss 实例中进行序列化和反序列化......
看this similar question,估计我的序列化过程肯定有问题,但是想不通。这是我正在使用的代码:
static InputStream serialize(Foo[] array) throws IOException {
ByteArrayOutputStream baos = null;
ObjectOutputStream oos = null;
try {
baos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(baos);
oos.writeObject(array);
return new ByteArrayInputStream(baos.toByteArray());
} finally {
close(oos);
close(baos);
}
}
static Foo[] deserialize(InputStream is) throws IOException, ClassNotFoundException {
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(is);
return (Foo[]) ois.readObject();
} finally {
close(ois);
}
}
编辑:我忘了提到数据在序列化后存储到磁盘,并在反序列化之前从那里读取。所以也许这就是它被破坏的地方。阅读我只使用new FileInputStream(file)。写,我用这个:
static void write(File file, InputStream is) throws IOException {
FileWriter fw = null;
InputStreamReader isr = null;
try {
fw = new FileWriter(file, true);
isr = new InputStreamReader(is);
char[] buffer = new char[8096];
int bytesRead;
while ((bytesRead = isr.read(buffer)) != -1) {
fw.write(buffer, 0, bytesRead);
}
} finally {
close(fw);
close(isr);
}
}
可能是因为我使用char[] 作为缓冲区,但输入流是从byte[] 生成的?这应该不是问题吧?
【问题讨论】:
-
byte[]到char[]的转换正是问题所在,请查看我的答案。切勿使用Writer处理二进制数据。
标签: java serialization deserialization bigdecimal