当前位置: 首页 > 知识库问答 >
问题:

二进制数据的Java序列化过程中的InvalidClassException

何向荣
2023-03-14

在我的实现中,我使用Java序列化在一组二进制对象之间发送,从通知头开始,通知头告诉要传递多少对象以及它们各自的大小。只是从简单的测试开始,我能够成功地传送头对象,然后我尝试只发送一个1024字节的数据对象。然而,在运行测试之后,我观察到以下情况:

  • 第一个数据对象已成功传递并已接收。
  • 当我发送第二个对象时,我看到来自第一个对象的一些数据仍然作为第二个数据集的前缀;从而截断第二个对象和InvalidClassException

有人能提供一些关于什么是这个问题和如何解决这个问题的指示吗?

接收器线程run()方法如下所示。

public void run() {

    while (mRunning) {
        try {

            // Receive the serialized object
            byte[] buf = new byte[1024];
            DatagramPacket packet = new DatagramPacket(buf, buf.length);
            socket.receive(packet);
            System.out.println("SERVER: data received: ");

            // Display the serialized object. 
            byte[] data = packet.getData();
            System.out.println(Arrays.toString(data));

            ByteArrayInputStream in = new ByteArrayInputStream(data);
            ObjectInputStream is = new ObjectInputStream(in);
            try {
                Object obj = is.readObject();
                if (obj instanceof DatakNotification) {
                    System.out.println("Data notification received: ");
                } else if (obj instanceof DataChunk) {
                    System.out.println("Data Chunk received: ");
                }
                System.out.println(obj);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        } catch (IOException e) {
            e.printStackTrace();
            mRunning = false;
        }
    }
    socket.close();
}

在日志中,我看到如下内容。

第一个对象(标题)

SERVER: data received: 
[-84, -19, 0, 5, 115, 114, 0, 47, 99, 111, 109, 46, 99, 111, 110, 97, 46, 118, 105, 100, 101, 111, 99, 108, 105, 101, 11
0, 116, 46, 99, 104, 117, 110, 107, 103, 101, 110, 46, 66, 108, 111, 99, 107, 78, 111, 116, 105, 102, 105, 99, 97, 116, 
105, 111, 110, -41, 62, 52, -41, -16, 78, 119, 0, 2, 0, 5, 73, 0, 10, 109, 66, 108, 111, 99, 107, 83, 105, 122, 101, 73,
 0, 10, 109, 67, 104, 117, 110, 107, 83, 105, 122, 101, 73, 0, 14, 109, 76, 97, 115, 116, 67, 104, 117, 110, 107, 83, 10
5, 122, 101, 73, 0, 12, 109, 84, 111, 116, 97, 108, 67, 104, 117, 110, 107, 115, 76, 0, 8, 109, 66, 108, 111, 99, 107, 7
3, 100, 116, 0, 18, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 120, 112, 0, 0, 10
1, 48, 0, 0, 4, 0, 0, 0, 1, 48, 0, 0, 0, 26, 116, 0, 36, 97, 53, 100, 48, 51, 54, 52, 55, 45, 54, 52, 51, 52, 45, 52, 55
, 98, 100, 45, 97, 101, 55, 51, 45, 55, 102, 57, 53, 49, 48, 52, 102, 55, 49, 98, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 

服务器:接收的数据:[-84,-19,0,5,115,114,0,39,99,111,109,46,99,111,110,97,46,118,105,100,101,111,99,108,105,101,11 0,116,46,99,104,117,110,107,103,101,110,46,68,97,116,97,67,104,117,110,107,-95,-44岁,27,37,-39,-34岁,12,17,2,0,5,73,0,7号,109,76,101,110,103,116,104,90,0,7号,109,77,97,114,107,101,100,73,0,12,1 09,83,101,113,117,101,110,99,101,78,117,109,91,0,4,109,66,117,102,116,0,2,91,66,76,0,8,109,6 7,104,117,110,107,73,100,116,0,18,76,106,97,118,97,47,108,97,110,103,47,83,116,114,105,110,103,59,120,112,0,0,4,0,0,0,0,0,0,117,114,0,2,91,66,-84,-13,23,-8,6,8,84,-32岁,2,0,0,120,112,0,0,4,0,70,76,86,1,1,0,0,0,0,9,0,0,0,0,0,0,0,0,2,0,10,111,110,77,101,11,6,97,68,97,116,97,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,119<...>-124,-7,-22,-22,-62,86,12,1,45,29,-126,-128,24,6,-48,96,3,-53,-15,-95,-24,48,31,-12,-12,-12,-12,-12,-

java.io.InvalidClassException: com.dataxfer.chunkgen.DataChunk; local class incompatible: stream classdesc serialVersionUID = -6785768889157546991, local class serialVersionUID = 2835159210520537273
    at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:617)
    at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1622)
    at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1517)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1350)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370)
    at com.dataxfer.transceiver.LocalUdpReceiver.run(LocalUdpReceiver.java:62)

共有1个答案

邓俊材
2023-03-14

这意味着编写器和读取器的serialversionuid不匹配。这是因为编写器和读取器上该类的代码不同。

这意味着读取的serialVersionUID需要硬编码以匹配写入器。

尝试设置

private static final long serialVersionUID = -6785768889157546991L;
 类似资料:
  • 问题内容: 我有一些二进制数据,它们在Python中是字节字符串数组的形式。 是否有一种可移植的方式来序列化其他语言可以读取的数据? JSON丢失了,因为我刚刚发现它没有存储二进制数据的真正方法。其字符串应为Unicode。 我不想使用,因为我不想存在安全风险,因此将其限制在其他Python程序中使用。 有什么建议吗?我真的很想使用内置库(或至少是标准Anaconda发行版中的一个库)。 问题答案

  • 本文向大家介绍Java,C#使用二进制序列化、反序列化操作数据,包括了Java,C#使用二进制序列化、反序列化操作数据的使用技巧和注意事项,需要的朋友参考一下 java使用二进制序列化、反序列化的操作首先,要引入java.io下面相关包,或者直接写import java.io.*; 下面,为了书写操作的方便,采用复制文件,和throws声明异常的方式来写 初略代码,仅供参考! C#使用二进制序列化

  • 在我的Android应用程序中,我创建了一个序列化的ArrayList并使用writeObject()将其写成二进制文件。我想把这个文件复制到PC上,读入一个程序(我需要用C++编写),在那里我会查看/编辑信息,把它写回文件,然后把它发送回Android设备,在那里它会被正确地解释。 是否存在序列化对象的结构定义?

  • 问题内容: 我必须报价, 1.将帐户保存到二进制(序列化)文件中。2.从二进制(序列化)文件加载(重新创建)帐户。 因此,首先,我正在查找确切的例子,而我却迷失了自己,在同样的情况下,人们提到xml,在我的脑海中,我认为它的意思像01010011000(二进制),而当我查看其他代码时,它看起来就像是正常的文本文件保存。 他到底是什么意思,有人可以举一个例子,或者给我一个更好地阐明这一点的网站吗?一

  • 本文向大家介绍什么是C#中的二进制序列化和反序列化?如何在C#中实现二进制序列化?,包括了什么是C#中的二进制序列化和反序列化?如何在C#中实现二进制序列化?的使用技巧和注意事项,需要的朋友参考一下 将对象转换为非人类可读格式的二进制格式称为二进制序列化。 将二进制格式转换回人类可读格式称为反序列化? 为了在C#中实现二进制序列化,我们必须使用库System.Runtime.Serializati

  • 问题内容: 几个月前,我将java.io.Serializable对象序列化为文件。现在,我需要阅读内容,但是从那以后,serialVersionUID发生了变化,现在我遇到了“类不兼容”错误。我知道一个事实,即没有任何数据成员已更改,因此唯一的障碍是serialVersionUID检查。 有没有办法禁用检查或修改二进制文件中的serialVersionUID? 澄清说明 这个问题是假设我无法编辑