Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/399.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java StreamCorruptedException试图反序列化从SharedReferences读取的对象_Java_Android_Serialization_Sharedpreferences_Deserialization - Fatal编程技术网

Java StreamCorruptedException试图反序列化从SharedReferences读取的对象

Java 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

我正在尝试从对象内部序列化对象,并使用以下答案对其进行反序列化:

但是我在反序列化时得到StreamCorruptedException

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不支持字节数组,这意味着当您将字符串转换为字节数组时,它会更改流并损坏数据

所以你有三个选择:

  • 存储为文件(内部/外部)
  • 以blob形式存储在数据库中
  • 将购物车中的每个项目保存为共享首选项中的单个项目
  • (并确保该项也是可序列化的,以防止以后出现异常)

    TL:DR将可序列化类保存为字符串,但将其转换回字节数组时,将出现此错误

    测试用例 以下测试适用于Android和桌面Java。此测试是使用Gradle项目完成的,但是您可以转到ApacheCommons,根据您的项目找到不同的依赖项。依赖关系用于在字节数组和类之间来回转换

    测试所需的依赖关系:

    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