【问题标题】:Java SerializationJava 序列化
【发布时间】:2013-03-25 04:02:16
【问题描述】:

我现在正在学习如何使用Java 语言进行序列化。我已阅读有关该主题的一些帖子和文档,并尝试做一个简单的示例(如下)

public class SterializeObject implements java.io.Serializable{

        /**
         * 
         */
        private static final long serialVersionUID = 1L;

        private String name;
        private transient int code;

        public SterializeObject (String n, int c){
            name = n;
            code = c;
        }

        public void printAtributes (){
            System.out.println("name: " + name + "; code: " + code);
        }
    }

    public class MainClass {
        public static void main(String[] agrs) {
            SterializeObject ob1 = new SterializeObject("ana", 1);
            SterializeObject ob2 = new SterializeObject("rita", 2);

            try {
                FileOutputStream fileOut = new FileOutputStream("file.data");
                ObjectOutputStream outObj = new ObjectOutputStream(fileOut);
                outObj.writeObject(ob1);
                outObj.writeObject(ob2);
                outObj.close();
                System.out.println("Objects were serialized!");
            } catch (IOException e) {
                e.printStackTrace();
            }

            ArrayList<SterializeObject> list = new ArrayList<SterializeObject>();
            try {
                FileInputStream fileInput = new FileInputStream("file.data");
                ObjectInputStream inputObj = new ObjectInputStream(fileInput);
                Object o;
                try {
                    while ((o = inputObj.readObject()) != null) {
                        list.add((SterializeObject) o);
                    }
                } catch (ClassNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    System.out.println("Erro foi aqui! (1)");
                }

                inputObj.close();
                fileInput.close();
            } catch (IOException e) {
                e.printStackTrace();
                System.out.println("Erro foi aqui! (2)");
            }

            for (int i = 0; i < list.size(); ++i) {
                list.get(i).printAtributes();
            }
        }
    }

我创建了一个Class SterializeObject implements java.io.Serializable 有两个变量:一个string(名称)和一个int(代码),它是瞬态的。然后我主要生成该类的两个实例,并尝试将其写入文件中,我已经成功完成了!之后,我尝试用循环读取这两个对象..这是我的问题..因为ObjectInputStream 没有某种方法来查看我们是否最终。因此,我尝试处理这种情况:(o = inputObj.readObject()) != null

My output is this:
java.io.EOFException
    at java.io.ObjectInputStream$BlockDataInputStream.peekByte(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.readObject(Unknown Source)
    at MainClass.main(MainClass.java:30)
Objects were serialized!
Erro foi aqui! (2)
name: ana; code: 0
name: rita; code: 0

我得到了对象,但我得到了一个错误,因为我认为是试图访问不存在的东西。

有人可以告诉我其他方法吗?

最好的问候。

【问题讨论】:

  • readObject 在到达文件末尾时会引发异常,它不会像您的代码所暗示的那样返回 null
  • 我不知道该怎么做,所以我就这样尝试了!

标签: java serialization


【解决方案1】:

读取与写入对象数量一样多的对象,或者写入对象列表本身,而不是一个接一个地写入每个对象。

(或者依靠EOFException来检测流的结束,但这很难看)。

【讨论】:

  • 嗯..我很抱歉这个问题,但是如何编写对象列表本身?谢谢
  • 您将两个对象存储在ArrayList&lt;SterializeObject&gt; 中,然后调用 writeObject(arrayList)。在接收端,您读取一个对象并将其转换为 List&lt;SterializeObject&gt;
  • 哦,我明白了!非常感谢..我会努力的!
【解决方案2】:

正如你们中的许多人告诉我的那样,我创建了一个 ArrayList 并序列化了 ArrayList。 我的代码是:

public class MainClass {
    public static void main(String[] agrs) {
        SterializeObject ob1 = new SterializeObject("ana", 1);
        SterializeObject ob2 = new SterializeObject("rita", 2);

        ArrayList <SterializeObject> list = new ArrayList<>();
        list.add(ob1);
        list.add(ob2);

        ArrayList <SterializeObject> input = new ArrayList<SterializeObject>();

        try {
            FileOutputStream fileOut = new FileOutputStream("file.data");
            ObjectOutputStream outObj = new ObjectOutputStream(fileOut);
            outObj.writeObject(list);
            outObj.close();
            System.out.println("Objects were serialized!");
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            FileInputStream fileInput = new FileInputStream("file.data");
            ObjectInputStream inputObj = new ObjectInputStream(fileInput);
            Object o;
            try {
                input = (ArrayList<SterializeObject>) inputObj.readObject();

            } catch (ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                System.out.println("Erro foi aqui! (1)");
            }

            inputObj.close();
            fileInput.close();
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("Erro foi aqui! (2)");
        }

        for (int i = 0; i < input.size(); ++i) {
            input.get(i).printAtributes();
        }
    }
}

输出是: 对象被序列化了! 姓名:安娜;代码:0 姓名:丽塔;代码:0

感谢您的帮助!

【讨论】:

    【解决方案3】:

    同时关闭 FileOutputStream 和 ObjectOutputStream

    fileOut.close();
    

    【讨论】:

    • 这不能回答问题,而且是错误的。关闭 ObjectOutputStream 会自动关闭包装的 FileOutputStream。
    【解决方案4】:

    为什么不将这两个对象都添加到 ArrayList,然后序列化 ArrayList。然后你只需要反序列化 ArrayList,它就会被两个对象填充。

    【讨论】:

      【解决方案5】:

      您可以通过将 readObject 调用放在 try-catch 块中并捕获您收到的 EOFException 来实现此目的,这表明您已读取所有对象。

      【讨论】:

      • 感谢您的帮助!好主意!
      【解决方案6】:

      用这段代码替换你的while循环

      do{
              try
              {
                  o = inputObj.readObject();
                  list.add((SterializeObject) o);
              }
              catch(EOFException e)
              {
                  o = null;
              }
      }while (o != null);
      

      【讨论】:

      • 感谢您的帮助!我创建了一个 ArrayList 但这种方式也很好!我也会试试的!谢谢
      【解决方案7】:

      与其使用 JDK 的 ObjectInputStream / ObjectOutputStream 进行序列化,不如考虑使用 Java-to-JSON 和 JSON-to-Java 库,如 json-io (https://github.com/jdereg/json-io)。它将处理一个对象数组作为根,一个包含循环的对象图,等等。使用这样的库,您无需确保您的对象实现 Serializable 或 Externalizable。

      执行序列化的示例代码:

      // Serialize an instanceo of the class EmployeeRecord emp
      String json = JsonWriter.objectToJson(emp); 
      
      
      // Deserialize it
      EmployeeRecord e = JsonReader.jsonToJava(json);
      

      序列化的 JSON 可以返回到浏览器,浏览器可以直接读入,Javascript 代码可以对其进行操作。使用 Java 的 ObjectInputStream / ObjectOutputStream 库无法[轻松] 实现。库只有83K,没有其他依赖。

      【讨论】:

        猜你喜欢
        • 2013-01-08
        • 1970-01-01
        • 2018-11-10
        • 2011-02-22
        • 2019-03-17
        • 2023-03-04
        相关资源
        最近更新 更多