Java StreamCorruptedException试图反序列化从SharedReferences读取的对象
我正在尝试从对象内部序列化对象,并使用以下答案对其进行反序列化: 但是我在反序列化时得到StreamCorruptedExceptionJava StreamCorruptedException试图反序列化从SharedReferences读取的对象,java,android,serialization,sharedpreferences,deserialization,Java,Android,Serialization,Sharedpreferences,Deserialization,我正在尝试从对象内部序列化对象,并使用以下答案对其进行反序列化: 但是我在反序列化时得到StreamCorruptedException java.io.StreamCorruptedException W/System.err: at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:2065) W/System.err: at java.io.ObjectInputStream.<init
java.io.StreamCorruptedException
W/System.err: at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:2065)
W/System.err: at java.io.ObjectInputStream.<init>(ObjectInputStream.java:371)
W/System.err: at ShoppingCart.load(ShoppingCart.java:154)
由于上下文
不可序列化,因此我将其设置为瞬态
我做错了什么?首先,在我看来,您不能将可序列化文件放入SharedPref中 我尝试使用字符串值保存到数据库,并将其转换回字节数组。(我可以将字节数组作为blob存储在数据库中)。当我使用字符串时,字节数组得到了错误的格式,这触发了与您现在遇到的相同的异常:StreamCorrupedException 当我得到这个错误并进行研究时,我从中得到的是StreamCorruptedException意味着你对流做了一些“坏”的事情,这破坏了格式 现在,我们来看看解决方案 当我尝试此操作时,将其保存为字符串并加载回字节数组,不同的字节不一定以保存时的相同格式加载回。这是您得到异常的时候。您试图从字符串加载字节数组,但当您将字节数组应用于类时,它最终会成为损坏的字节数组 基本上,不要将其保存为字符串并将其转换为字节数组!我所做的是将它保存为一个字节数组,我使用一个数据库,数据库支持这一点。但在我看来,共享pref并不是。因此,基本上,您不能使用字符串并将其转换为字节数组来保存然后加载。您必须使用内部/外部存储(基本上是文件)或使用模式设置为blob的数据库。但是共享pref不支持字节数组,这意味着当您将字符串转换为字节数组时,它会更改流并损坏数据 所以你有三个选择:
compile 'org.apache.commons:commons-lang3:3.5'
示例类:
public class Something implements Serializable{
public static final long serialVersionUID = 0L;
int x = 12;
}
样本测试:
Something instance = new Something();
String class_ = SerializationUtils.serialize(instance).toString();
byte[] bytes = class_.getBytes();
instance = (Something) SerializationUtils.deserialize(bytes);
输出:
Exception in thread "main" org.apache.commons.lang3.SerializationException: java.io.StreamCorruptedException: invalid stream header: 5B424036
at org.apache.commons.lang3.SerializationUtils.deserialize(SerializationUtils.java:229)
at org.apache.commons.lang3.SerializationUtils.deserialize(SerializationUtils.java:265)
at com.core.Launcher.main(Launcher.java:22)
Caused by: java.io.StreamCorruptedException: invalid stream header: 5B424036
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:857)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:349)
at org.apache.commons.lang3.SerializationUtils.deserialize(SerializationUtils.java:221)
... 2 more
Process finished with exit code 1
线程“main”org.apache.commons.lang3.SerializationException中的异常:java.io.StreamCorruptedException:无效流头:5B424036
位于org.apache.commons.lang3.SerializationUtils.deserialize(SerializationUtils.java:229)
位于org.apache.commons.lang3.SerializationUtils.deserialize(SerializationUtils.java:265)
位于com.core.Launcher.main(Launcher.java:22)
原因:java.io.StreamCorruptedException:无效流头:5B424036
位于java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:857)
位于java.io.ObjectInputStream。(ObjectInputStream.java:349)
位于org.apache.commons.lang3.SerializationUtils.deserialize(SerializationUtils.java:221)
... 还有两个
进程已完成,退出代码为1
在我的测试中,这抛出StreamCorruptedException,它基本上显示了一件事:不能将类转换为字节数组,然后转换为字符串,再转换回字节数组
注意:这个测试用例是在Windows10计算机和Android 7(S6 edge)上执行的,它抛出了相同的错误(stacktrace更改,因为有两个不同的项目)
总结: 保存和加载字节数组工作正常。在保存和加载字节数组时,中间包含一个字符串,它会损坏流。 解决方案: 不要使用字符串部分保存,以便能够在不受支持的平台上保存。该平台在本例中为Sharedprefs。使用文件或数据库(带有blob字段)是在Android设备上本地保存字节数组的唯一方法。通过互联网传输数据是一个完全不同的话题,我不打算涉及 因此,为了用字节进行序列化和反序列化,必须将其保存为文件或数据库。在字符串之间来回转换会给您带来问题
最后,此错误与不可变量字段无关。这会引发另一个错误(
NotSerializableException
)。谢谢您的时间。我知道notserializableeexception
我只是在解释transient
这件事。非常感谢你
Something instance = new Something();
String class_ = SerializationUtils.serialize(instance).toString();
byte[] bytes = class_.getBytes();
instance = (Something) SerializationUtils.deserialize(bytes);
Exception in thread "main" org.apache.commons.lang3.SerializationException: java.io.StreamCorruptedException: invalid stream header: 5B424036
at org.apache.commons.lang3.SerializationUtils.deserialize(SerializationUtils.java:229)
at org.apache.commons.lang3.SerializationUtils.deserialize(SerializationUtils.java:265)
at com.core.Launcher.main(Launcher.java:22)
Caused by: java.io.StreamCorruptedException: invalid stream header: 5B424036
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:857)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:349)
at org.apache.commons.lang3.SerializationUtils.deserialize(SerializationUtils.java:221)
... 2 more
Process finished with exit code 1