运行时出现这个问题一直找不到解决

Exception in thread "main" java.io.StreamCorruptedException: invalid stream header: 4E000000

读取输入流的过程中发现了无效的流头。这可能是因为输入流的格式不正确导致的。具体原因可能是文件损坏、文件类型不匹配、文件编码格式错误

基于new bing部分指引作答:
该错误通常表示在尝试反序列化对象时发生了问题。StreamCorruptedException异常一般出现在以下几种情况下:

  1. 序列化和反序列化的版本不匹配:如果尝试使用不同版本的Java进行序列化和反序列化操作,就会导致该异常。请确保序列化和反序列化的代码在相同的Java版本下运行。

  2. 对象的类定义已更改:如果你在序列化对象之后修改了对象的类定义,再进行反序列化会导致异常。确保在反序列化之前,对象的类定义没有发生变化。

  3. 使用错误的输入源进行反序列化:请检查你正在读取的输入源是否正确。例如,如果你尝试从非序列化的数据中读取,就可能导致该异常。

针对你提到的错误信息 "java.io.StreamCorruptedException: invalid stream header: 4E000000",这可能是由于解析非序列化数据或数据损坏引起的。请确保你的输入源是正确的,并且数据没有损坏。

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 这篇文章:Java Stream 底层原理 也许能够解决你的问题,你可以看下
  • 除此之外, 这篇博客: java.io.StreamCorruptedException: invalid stream header中的 问题描述 部分也许能够解决你的问题, 你可以仔细阅读以下内容或者直接跳转源博客中阅读:

    问题:

    在一个用户给另一个仍未上线的用户(即离线用户)发送消息时,由于对方用户离线,服务端会将message先存储起来,等待该用户上线再转发message给他。但是当我这样处理的时候,出现了如下错误。

    java.io.StreamCorruptedException: invalid stream header: 7371007E
    	at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:936)
    	at java.io.ObjectInputStream.<init>(ObjectInputStream.java:394)
    	at com.hspedu.qqclient.service.ClientConnectServerThread.run(ClientConnectServerThread.java:23)
    

    在这里插入图片描述
    而且,我发现,该离线用户一旦上线,服务端是会正常发送他离线期间收到的信息给他的,关键是接收出了问题。
    服务端没有报错:
    在这里插入图片描述
    客户端报错,但是它是在收到一条正确的离线留言之后才产生错误的:
    在这里插入图片描述

    给出关键源代码如下:

    服务端

    //                    将离线消息都发过去
                        oos=new ObjectOutputStream(ManageClientThreads.getClientThread(user.getUserId()).getSocket().getOutputStream());
                        if(offlineDb.containsKey(user.getUserId())){
                            ArrayList<Message> messages = offlineDb.get(user.getUserId());
                            for (Message offlinems:messages
                            ) {
                                System.out.println(offlinems.getContent());
                                oos.writeObject(offlinems);
                            }
                            offlineDb.remove(user.getUserId());
                            System.out.println(user.getUserId()+"上线了,服务端已经转发完成所有离线消息");
                        }
    

    客户端

    package com.hspedu.qqclient.service;
    
    import com.hspedu.qqcommon.Message;
    import com.hspedu.qqcommon.MessageType;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.net.Socket;
    
    public class ClientConnectServerThread extends Thread{
    //    该线程需要持有socket对象
        private  Socket socket;
    //构造器接收socket
        public ClientConnectServerThread(Socket socket) {
            this.socket = socket;
        }
        private ObjectInputStream ois;
        @Override
        public void run() {
    //        因为Thread需要后台和服务器通信,所以我们一直循环
            while(true){
                System.out.println("客户端线程,等待读取从服务器端发送过来的消息");
                try {
                    ois= new ObjectInputStream(socket.getInputStream());
    //                如果服务器没有发送Message对象,线程就会阻塞在这里
                    Message message=(Message)(ois.readObject());
    //如果读取到的是服务端返回的在线用户列表
                    if(message.getMesType().equals(MessageType.MESSAGE_RET_ONLINE_FRIEND)){
                        //取出在线列表信息并显示
                        String[] onlineUsers=message.getContent().split(" ");
                        System.out.println("============当前在线用户列表=============");
                        for (int i = 0; i < onlineUsers.length; i++) {
                            System.out.println(onlineUsers[i]);
                        }
                    }else if(message.getMesType().equals(MessageType.MESSAGE_COMM_MES)){
                        //收到私聊信息
                        System.out.println("我"+message.getGetter()+"收到了来自"+message.getSender()+"的私聊信息:"+message.getContent());
                    }else if(message.getMesType().equals(MessageType.MESSAGE_TO_ALL_MES)){
                        //收到群发信息
                        System.out.println("我收到了来自"+message.getSender()+"的群发信息:"+message.getContent());
                    }else if(message.getMesType().equals(MessageType.MESSAGE_NEWS)){
                        System.out.println("我收到了来自服务端推送的新闻:"+message.getContent());
                    }
                    else{
                        System.out.println("是其他类型的message,暂时不处理");
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
            }
        }
    
        public Socket getSocket() {
            return socket;
        }
    
        public void setSocket(Socket socket) {
            this.socket = socket;
        }
    }
    

    该文件全部源代码:

    服务端

    package com.hspedu.qqserver.service;
    
    import com.hspedu.qqcommon.Message;
    import com.hspedu.qqcommon.MessageType;
    import com.hspedu.qqcommon.User;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.ArrayList;
    import java.util.HashMap;
    
    public class QQServer {
        private ServerSocket ss = null;
        //    创建一个集合,存放多个用户,如果是这些用户登录,就认为合法
        private static HashMap<String, User> validUsers = new HashMap<>();
        private static HashMap<String, ArrayList<Message>> offlineDb =new HashMap<>();
        static {//在静态代码块内初始化validUsers
            validUsers.put("100", new User("100", "123456"));
            validUsers.put("200", new User("200", "123456"));
            validUsers.put("300", new User("300", "123456"));
            validUsers.put("李东海", new User("李东海", "李赫宰"));
            validUsers.put("李赫宰", new User("李赫宰", "李东海"));
        }
    
        public static HashMap<String, ArrayList<Message>> getOfflineDb() {
            return offlineDb;
        }
    
        //    验证用户是否有效的方法
        private boolean checkUser(String userId, String password) {
            User user = validUsers.get(userId);
            if (user != null && user.getPassword().equals(password)) {
                return true;
            }
            return false;
        }
    
    
        public QQServer() {
            System.out.println("服务端在9999端口监听...");
            try {
                ss = new ServerSocket(9999);
    
                SendNewsToAllService sendNewsToAllService = new SendNewsToAllService();
                sendNewsToAllService.start();
    
    
                //当和某个客户端建立连接之后,会继续监听,因为应该用while循环
                while (true) {
                    Socket socket = ss.accept();
                    //得到socket关联的对象输入流
                    ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
                    //得到socket关联的对象输出流
                    ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
                    User user = (User) (ois.readObject());
    //            验证
                    Message message = new Message();
                    if (checkUser(user.getUserId(), user.getPassword())) {
                        message.setMesType(MessageType.MESSAGE_LOGIN_SUCCEED);
    //                回复客户端一个Message对象
                        oos.writeObject(message);
    //创建一个线程,和客户端保持通信,该线程需要持有socket对象
                        ServerConnectClientThread serverConnectClientThread = new ServerConnectClientThread(socket, user.getUserId());
    //               启动线程
                        serverConnectClientThread.start();
    //           把该线程对象放到集合中管理
                        ManageClientThreads.addClientThread(user.getUserId(), serverConnectClientThread);
    
    //                    将离线消息都发过去
                        oos=new ObjectOutputStream(ManageClientThreads.getClientThread(user.getUserId()).getSocket().getOutputStream());
                        if(offlineDb.containsKey(user.getUserId())){
                            ArrayList<Message> messages = offlineDb.get(user.getUserId());
                            for (Message offlinems:messages
                            ) {
                                System.out.println(offlinems.getContent());
                                oos.writeObject(offlinems);
                            }
                            offlineDb.remove(user.getUserId());
                            System.out.println(user.getUserId()+"上线了,服务端已经转发完成所有离线消息");
                        }
    
    
                    } else {
                        System.out.println("登录失败");
                        message.setMesType(MessageType.MESSAGE_LOGIN_FAIL);
                        oos.writeObject(message);
                        socket.close();
                    }
                }
            } catch (IOException | ClassNotFoundException e) {
                e.printStackTrace();
            } finally {
                try {
                    ss.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    

    客户端

    // 客户端全部代码都在上面放了
    


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^