反序列化EOF异常,Serialize可能会不正确地写入文件

时间:2016-01-24 22:36:52

标签: java serialization deserialization

package thegreatestrpgevermade;
import java.util.HashMap;
import java.lang.reflect.*;
import javax.swing.JPanel;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.io.Externalizable;
import javax.swing.Action;
import javax.swing.AbstractAction;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.io.ObjectInputStream;
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
public class Room implements Externalizable
{
    static Room room;
     HashMap<Integer,ParentObject> ParentObjectMap ;
     int roomNumber ;
     int width  ;
     int height ;
     int idNumber ;
    static  ActionClass actionClass;
    static  JFrame creationWindow;
    static  JPanel creationPanel;
    static  JButton addObjectButton;
    static  JButton removeObjectButton;
    static  JButton finalizeRoomButton;
    static JTextField classNameField;
    static  JTextField xSpawnField;
    static  JTextField ySpawnField;
    static  JTextField argument3Field;
    static  JTextField numberOfArgumentsField;
    static  JTextField roomNumberField;
    static  JTextField roomWidthField;
    static  JTextField roomHeightField;

    public Room()
    {
     HashMap<Integer,ParentObject> ParentObjectMap = new HashMap();;
     int roomNumber=0 ;
     int width =0 ;
     int height =0;
     int idNumber =0;
    }
    static Object StringToObj (String name, Object[] argArray, int numArgs)
    {
        try
        {
        Class o = Class.forName(name);
        Class argTypes[] = new Class[numArgs];
        //System.out.println("A");
        for(int I = 0; I<numArgs ; I ++)
        {
            argTypes[I] = Class.forName(argArray[I].getClass().getName());//.Type;
            if (Class.forName(argArray[I].getClass().getName()) == Integer.class)
            {
                argTypes[I] = Integer.TYPE;
            }
            //System.out.println(argArray[I].getClass().getName());
        //argTypes[1] = Integer.TYPE;
        }
        Constructor constructor = o.getConstructor(argTypes);
        //Object arguments[] = new Object[numArgs];
        //System.out.println("C");
        //arguments[0] = A;
        //arguments[1] = B;
        Object newObject = constructor.newInstance(argArray);
        //System.out.println("D");
        return newObject;
        }

        catch(ClassNotFoundException cnfe)
        {
            System.out.println("Class not found exception ");
            System.exit(1);
        }
        catch(NoSuchMethodException nsme)
        {
            System.out.println("No Such Method Exception");
            System.exit(1);
        }
        catch(InstantiationException instExcep)
        {
            System.out.println("Instantiation Exception");
            System.exit(1);
        }
        catch(IllegalAccessException iae)
        {
            System.out.println("Illegal Access Exception");
            System.exit(1);
        }
        catch(InvocationTargetException ite)
        {
            System.out.println("Invocation target exception");
            System.exit(1);
        }
        //so , sort through an array of all the sub classes of parent object, 
        //or maybe all the classes in the package, and test their getName
        //against the argument until it comes out right, then return that class. 
        System.out.println("String to Obj is broken");
        return null;
    }
    class ActionClass implements ActionListener
    {
       public void actionPerformed (ActionEvent e)
       {
           if(e.getSource() == addObjectButton)
           {
               Object[] arguments = new Object[Integer.parseInt(numberOfArgumentsField.getText())];
               arguments[0] = Integer.parseInt(xSpawnField.getText());
               arguments[1] = Integer.parseInt(ySpawnField.getText());
               //arguments[2] = idNumber;

               ParentObject placeHolder = (ParentObject)StringToObj("thegreatestrpgevermade." +
                       classNameField.getText(), arguments,Integer.parseInt(numberOfArgumentsField.getText()));
               placeHolder.IDNUMBER = idNumber;
               idNumber ++;
               ParentObjectMap.put(new Integer(idNumber),placeHolder);
               System.out.println("idnumber :" +placeHolder.IDNUMBER);
           }
           if(e.getSource() == removeObjectButton)
           {
              System.out.println(ParentObjectMap.get(0).spriteDirectory);
              System.out.println("removeObjectButton Pressed");                     
           }
           if(e.getSource() == finalizeRoomButton)
           {
               try
               {
                   roomNumber = Integer.parseInt(roomNumberField.getText());
                   width = Integer.parseInt(roomWidthField.getText());
                   height = Integer.parseInt(roomHeightField.getText());
                   FileOutputStream fos = new FileOutputStream("C:\\thegreatestrpgevermade\\room" 
                           + roomNumber +".ser");
                   ObjectOutputStream oos = new ObjectOutputStream(fos);
                   System.out.println("Finalize: room line 152");
                   oos.writeObject(room);
                   System.out.println("Finalize: room line 154");
                   oos.flush();
                   oos.close();
               }
               catch(IOException ioe)
               {
                   System.out.println("io exception room");
                   System.exit(1);
               } 
           }
       }
    }
    public  void InitializeCreationMode()
    {
       room = new Room();
       ParentObjectMap = new HashMap();
       actionClass = new ActionClass();
       creationWindow = new JFrame();
       creationPanel = new JPanel();
       addObjectButton = new JButton("Add Object");
       removeObjectButton = new JButton("Remove Object");
       finalizeRoomButton = new JButton("Finalize Room");
       classNameField = new JTextField("Class Name",20);
       xSpawnField = new JTextField("X Coordinate(arg1)" , 20);
       ySpawnField = new JTextField("Y Coordinate(arg2)" , 20);
       argument3Field = new JTextField("Argument 3" , 20);
       numberOfArgumentsField = new JTextField("Number Of Arguments" , 20);
       roomNumberField = new JTextField("Room Number" , 20);
       roomWidthField = new JTextField("Room Width" , 20);
       roomHeightField = new JTextField("Room Height" , 20);
       creationWindow.setSize(300,400);
       creationWindow.setResizable(false);
       creationWindow.setLocation(0,0);
       creationWindow.add(creationPanel);
       creationWindow.setDefaultCloseOperation(creationWindow.EXIT_ON_CLOSE);
       creationPanel.setSize(300,400);
       creationPanel.add(addObjectButton);
       creationPanel.add(removeObjectButton);
       creationPanel.add(finalizeRoomButton);
       creationPanel.add(roomNumberField);
       creationPanel.add(roomWidthField);
       creationPanel.add(roomHeightField);
       creationPanel.add(classNameField);
       creationPanel.add(numberOfArgumentsField); 
       creationPanel.add(xSpawnField);
       creationPanel.add(ySpawnField);
       creationPanel.add(argument3Field);
       addObjectButton.addActionListener(actionClass);
       removeObjectButton.addActionListener(actionClass);
       finalizeRoomButton.addActionListener(actionClass);
       creationWindow.setVisible(true);
       //im thinking ID numbers can't stay random.
        //so basically, say HERO hits ENEMY. if ENEMY gets hit, it gives 
        //HERO its ID number which can be put into the hashmap to modify
        // ENEMY'S health. 
    }
    public void readExternal(ObjectInput in)
    {
        try
        {

            idNumber = in.readInt();
            width = in.readInt();
            height = in.readInt();
            roomNumber = in.readInt();
           // ParentObjectMap = (HashMap)in.readObject();
        }
        catch(IOException ioe)
        {
            System.out.println(ioe.toString());
            ioe.printStackTrace();
        }
        catch(ClassNotFoundException cnfe)
        {
            System.out.println("cnfe exception readExternal");
        }
    }
    public void writeExternal(ObjectOutput out)
    {
        try
        {
            System.out.println("Checkpoint 1 writeExternal");
            out.writeInt(idNumber);
            System.out.println("Checkpoint 2 writeExternal: width:" + width);
            out.writeObject(width);
            System.out.println("Checkpoint 3 writeExternal : width:" + width);
            out.writeInt(height);
            System.out.println("Checkpoint 4 writeExternal");
            out.writeInt(roomNumber);
            System.out.println("Checkpoint 5 writeExternal");
            //out.writeObject(ParentObjectMap);
        }
        catch(IOException ioe)
        {
            System.out.println(ioe.toString());
            ioe.printStackTrace();
        }

    }
    /*public static void main(String[] args)
    {   
       room = new Room();
       room.InitializeCreationMode();
    }*/

}

另一个类是MainClass。我包括相关的片段。

            FileInputStream fis = new FileInputStream("C:\\thegreatestrpgevermade\\room0.ser");
            ObjectInputStream ois = new ObjectInputStream(fis);          
            room = (Room)ois.readObject();
 //           room = new Room();
            room.InitializeCreationMode();
            System.out.println("Room Width: " +room.width);

堆栈跟踪是这样的:

java.io.EOFException
at java.io.DataInputStream.readInt(DataInputStream.java:392)
at java.io.ObjectInputStream$BlockDataInputStream.readInt(ObjectInputStream.java:2820)
at java.io.ObjectInputStream.readInt(ObjectInputStream.java:971)
at thegreatestrpgevermade.Room.readExternal(Room.java:220)
at java.io.ObjectInputStream.readExternalData(ObjectInputStream.java:1837)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1796)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1350)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370)
at thegreatestrpgevermade.MainClass.main(MainClass.java:176)

Initialize创建模式方法创建一个带按钮和字段的jwindow 为宽度,高度等分配值。动作类侦听其按钮 并且finalize按钮序列化字段。序列化出了点问题。 在任何点打印出宽度给出零。我不知道为什么。

1 个答案:

答案 0 :(得分:1)

假设您的标题中有问题,答案是肯定的,文件写得不正确。但你不需要这一切。将其更改为实施Serializable而不是Externalizable,并删除readExternal()writeExternal()方法。