Java序列化问题

时间:2014-02-18 15:24:37

标签: java serialization

我有这个代码写一个对象:

FileOutputStream fileOut = new FileOutputStream("Model.ser");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(this);
out.close();
fileOut.close();

这个加载对象的代码:

Model m = null;
try {
    FileInputStream fileIn = new FileInputStream("Model.ser");
    ObjectInputStream in = new ObjectInputStream(fileIn);
    m = (Model) in.readObject();
    in.close();
    fileIn.close();
} catch (Exception e) {}

setStudentList(m.getStudentList());
setModuleList(m.getModuleList());

我很确定保存工作正常,因为当我在记事本中打开文件时,我看到了我保存的大部分数据,但是当我加载时,模块列表中没有数据。

完整源代码:

import java.io.*;
import java.util.*;

public class Model implements java.io.Serializable {

private Student[] studentList = new Student[0];
private Module[] moduleList = new Module[0];

public void menu() {
    while (true) {
        System.out.println ("MENU");
        System.out.println ("");
        System.out.println ("   1 - Run Tests");
        System.out.println ("   2 - Add Student");
        System.out.println ("   3 - Add Module");
        System.out.println ("   4 - Add Student To Module");
        System.out.println ("   5 - Save System (Text file)");
        System.out.println ("   6 - Load System (Text file)");
        System.out.println ("   7 - Save System (Serialized)");
        System.out.println ("   8 - Load System (Serialized)");
        System.out.println ("   9 - Print Report");
        System.out.println ("");
        System.out.print ("Enter choice: ");

        String input = keyboard.readString();

        switch (input) {
            case "1" :
                runTests();
                break;
            case "2" :
                System.out.print("First Name : ");
                String fN = keyboard.readString();
                System.out.print("Surname : ");
                String sN = keyboard.readString();
                System.out.print("Course Code : ");
                String c = keyboard.readString();
                System.out.print("User ID : ");
                String iD = keyboard.readString();
                AddStudent(iD, sN, fN, c);
                break;

            case "3" :
                System.out.print("Module Code : ");
                String code = keyboard.readString();
                String[] temp = new String[0];
                AddModule(code,temp);
                break;
            case "4" :
                System.out.print("Module Code : ");
                code = keyboard.readString();
                Module m = findAModule(code);
                if (m != null) {
                    System.out.print("User ID : ");
                    iD = keyboard.readString();
                    Student s = findAStudent(iD);
                    if (s != null) {
                        m.addThisStudent(s);
                    } else {
                        System.out.println("Student not found");
                    }
                } else {
                    System.out.println("Module not found");
                }
                break;
            case "5" :
                saveToTextFiles();
                break;
            case "6" :
                loadFromTextFiles();
                break;
            case "7" :
                saveSerialized();
                break;
            case "8" :

                break;
            case "9" :
                printReport();
                break;                  
        }
    }
}

public void runTests() {
    loadFromTextFiles();
    saveSerialized();
    printReport();
}

public void loadFromTextFiles() {
    studentList = new Student[0];
    moduleList = new Module[0];
    try {
        Scanner fileReader = new Scanner(new InputStreamReader(new FileInputStream("students.txt")));
        int num = fileReader.nextInt(); fileReader.nextLine();
        for (int i = 0; i < num; i++) {
            String u = fileReader.nextLine();
            String sn = fileReader.nextLine();
            String fn = fileReader.nextLine();
            String c = fileReader.nextLine();
            AddStudent(u, sn, fn, c);   
        }
        fileReader.close();

        fileReader = new Scanner(new InputStreamReader(new FileInputStream("modules.txt")));
        num = fileReader.nextInt(); fileReader.nextLine();
        for (int i = 0; i < num; i++) {
            String code = fileReader.nextLine();
            int numOfStudents = fileReader.nextInt(); fileReader.nextLine();
            String[] students = new String[numOfStudents];
            for (int j = 0; j < numOfStudents; j++) {
                students[j] = fileReader.nextLine();
            }
            AddModule(code, students);  
        }
        fileReader.close();
    } catch (IOException e) {}

}

public void saveToTextFiles () {
    try {
        PrintWriter outfile = new PrintWriter(new OutputStreamWriter (new FileOutputStream("students.txt")));
        outfile.println(studentList.length);
        for (int i = 0; i < studentList.length; i++) {
            outfile.println(studentList[i].getUID());
            outfile.println(studentList[i].getSN());
            outfile.println(studentList[i].getFN());
            outfile.println(studentList[i].getDegree());
        }
        outfile.close();

        outfile = new PrintWriter(new OutputStreamWriter (new FileOutputStream("modules.txt")));
        outfile.println(moduleList.length);
        for (int i = 0; i < moduleList.length; i++) {
            outfile.println(moduleList[i].getCode());
            outfile.println(moduleList[i].getStudents().length);
            for (int j = 0; j < moduleList[i].getStudents().length; j++) {
                outfile.println(moduleList[i].getStudents()[j]);
            }
        }
        outfile.close();
    } catch (IOException e) {}
}

public void saveSerialized() {
    try {
        FileOutputStream fileOut = new FileOutputStream("Model.ser");
        ObjectOutputStream out = new ObjectOutputStream(fileOut);
        out.writeObject(this);
        out.close();
        fileOut.close();

        FileOutputStream fileOut2 = new FileOutputStream("Module.ser");
        ObjectOutputStream out2 = new ObjectOutputStream(fileOut2);
        out2.writeObject(studentList);
        out2.close();
        fileOut2.close();

        FileOutputStream fileOut3 = new FileOutputStream("Student.ser");
        ObjectOutputStream out3 = new ObjectOutputStream(fileOut3);
        out3.writeObject(moduleList);
        out3.close();
        fileOut3.close();
    } catch (IOException e) {}
}

public void loadSerialized() {
    Model m = null;
    try {
         FileInputStream fileIn = new FileInputStream("Model.ser");
         ObjectInputStream in = new ObjectInputStream(fileIn);
         m = (Model) in.readObject();
         in.close();
         fileIn.close();
    } catch (Exception e) {}

    setStudentList(m.getStudentList());
    setModuleList(m.getModuleList());
}

private Module[] getModuleList() {
    return moduleList;
}

private Student[] getStudentList() {
    return studentList;
}

private void setModuleList(Module[] m) {
    moduleList = m.clone();
}

private void setStudentList(Student[] s) {
    studentList = s.clone();
}

private void AddModule(String code, String[] students) {
    int length = moduleList.length;
    Module NewArray[] = new Module[length + 1];
    for (int i = 0; i < length + 1; i++) {
        if (i < length) {
            NewArray[i] = new Module(moduleList[i]);
        }
    }
    NewArray[length] = new Module(code, students);
    moduleList = NewArray.clone();
}

private void AddStudent(String u, String sn, String fn, String c) {
    int length = studentList.length;
    Student NewArray[] = new Student[length + 1];
    for(int i = 0; i < length + 1; i++) {
        if (i < length) {
            NewArray[i] = new Student(studentList[i]);
        }
    }
    NewArray[length] = new Student(u, sn, fn, c);
    studentList = NewArray.clone();
}

public void printReport() {
    for (int i = 0; i < moduleList.length; i++) {
        System.out.println(moduleList[i].toString(this));
    }
}

public Student findAStudent(String uid) {
    for (int i = 0; i < studentList.length; i++) {
        if (studentList[i].getUID().compareTo(uid) == 0) {
            return studentList[i];
        }
    }
    return null;
}

public Module findAModule(String code) {
    for (int i = 0; i < moduleList.length; i++) {
        if (moduleList[i].getCode().compareTo(code) == 0) {
            return moduleList[i];
        }
    }
    return null;
}
}

1 个答案:

答案 0 :(得分:1)

查看您的代码示例,特别是switch语句:

switch (input) {

    ...

    case "8" :

        break;

    ...

}

我假设应该在那里调用方法loadSerialized但是它丢失了,并且在代码中的任何其他地方都没有被调用。

一旦你实际调用了进行加载的方法,代码就会生效,假设你已为serialVersionUIDStudent声明了Module

编辑:为什么使用序列化来保存对象是一个坏主意

简单来说,使用序列化来保存对象很脆弱。

对象的序列化表单与其类绑定。类往往会随着时间的推移而改变,这意味着旧的序列化实例无法加载到新的实例中。

虽然你可以通过设置serialVersionUID来解决这个问题,但是引入了一个问题的反转,在引入新字段的情况下,新的字段无法读入旧类的对象,这可能是如果您对已部署的系统执行滚动更新,则会出现问题。

还有许多其他原因 - 它不易读取(意味着你不能像数据库或XML / JSON doc那样更新它),它效率低等等。