为什么我的 HashSet 在 ORMLite 中序列化不正确?序列化时的尺寸似乎有误

问题描述 投票:0回答:1

我将应用程序中的字段保存为哈希集,定义如下:

@DatabaseField(dataType = DataType.SERIALIZABLE)
private HashSet<String> allUsers;

某些设备偶尔会出现错误,即该字段使用错误大小的字节进行序列化,因此无法反序列化。带有虚拟数据的错误消息示例:

java.sql.SQLException: Could not read serialized object from byte array: [-84, -19, 0, 5, 115, 114, 0, 17, 106, 97, 118, 97, 46, 117, 116, 105, 108, 46, 72, 97, 115, 104, 83, 101, 116, -70, 68, -123, -107, -106, -72, -73, 52, 3, 0, 0, 120, 112, 119, 12, 0, 0, 0, 16, 63, 64, 0, 0, 0, 0, 0, [this is the problem byte] 3, 116, 0, 4, 115, 111, 109, 101, 116, 0, 4, 100, 97, 116, 97, 120]

如果我更正大小字节以创建一个新数组,如下所示:

[-84, -19, 0, 5, 115, 114, 0, 17, 106, 97, 118, 97, 46, 117, 116, 105, 108, 46, 72, 97, 115, 104, 83, 101, 116, -70, 68, -123, -107, -106, -72, -73, 52, 3, 0, 0, 120, 112, 119, 12, 0, 0, 0, 16, 63, 64, 0, 0, 0, 0, 0, [correct size is 2] 2, 116, 0, 4, 115, 111, 109, 101, 116, 0, 4, 100, 97, 116, 97, 120]

然后我可以反序列化数组以找到包含两个字符串的 HashSet。

我想知道 HashSet 以这种方式被序列化为错误大小的字节的可能原因。我无法确定重现此问题的步骤,但它已在多个设备上发生。然而,运行该应用程序的绝大多数设备都没有这个问题。

我尝试通过序列化 HashSet,然后反序列化它,添加和删除对象,然后再次序列化来重现该问题。但我无法重现该问题。我想知道 Java 中的 HashSet 是否存在像这样错误序列化的已知原因。

java android serialization hashset ormlite
1个回答
0
投票

某些设备偶尔会出现错误,即该字段使用错误大小的字节进行序列化,因此无法反序列化。

我最好的猜测是某些东西正在修改另一个线程中的

HashSet
。 ORMLite 所做的就是将数据序列化到缓冲区中,然后将其存储为字节包。查看 SerializedType.sqlArgToJava(...) 中相当简单的代码。它基本上是在做:

ByteArrayOutputStream outStream = new ByteArrayOutputStream();
objOutStream = new ObjectOutputStream(outStream);
objOutStream.writeObject(obj);
objOutStream.close();
return outStream.toByteArray();

正如您所提到的,序列化的

HashSet
表示其大小为 3,但集合中仅存储 2 个字符串。我可以看到当一个元素添加到 HashSet 并且大小字段已更新但底层节点数组未更新时会发生这种情况。怀疑序列化流的问题不在字符串或其他数据的中间。

© www.soinside.com 2019 - 2024. All rights reserved.