【问题标题】:java deserialize exceptionjava反序列化异常
【发布时间】:2015-01-14 09:50:49
【问题描述】:

我在程序开始时遇到反序列化问题。

public static void main(String[] args) throws IOException, ClassNotFoundException{

        Test object = new Test(); // Test implements Serializable

        //start
        deserialize();  

        //do something

        //end
        serialize(object);         
    }

public static void deserialize()
    {
        test object = null;

        try
          {
             FileInputStream file= new FileInputStream(".../Example.ser");
             if(file.read()!=-1) //the first time the file will be empty
             {
                 ObjectInputStream read= new ObjectInputStream(file); //here an exception is thrown the second time the program is started
                 object  = (Test) read.readObject();
                 object .printdata();
                 read.close();
                 file.close();
             }
             else
             {
                 file.close(); 
             }
          }catch(IOException i)
          {
             i.printStackTrace();
             return;
          }catch(ClassNotFoundException c)
          {
             c.printStackTrace();
             return;
          } 
    }

    public static void serialize(Test object)
    {   
        try
        {
           FileOutputStream file =
           new FileOutputStream(".../Example.ser");
           ObjectOutputStream write = new ObjectOutputStream(file );
           write .writeObject(object);
           write .close();
           file .close();
        }catch(IOException i)
        {
            i.printStackTrace();
        }
    }

如果要切换序列化和反序列化,或者如果我在序列化后调用反序列化,程序就可以工作。 它第一次运行良好,但如果我第二次启动它反序列化 @ ObjectInputStream read= new ObjectInputStream(file);引发流损坏的异常。

在程序启动时,必须对序列化文件进行反序列化和打印,正如我所说,如果切换调用,然后将反序列化的调用复制回顶部,它可以工作,但如果它保持这样就不行。第一次运行但第二次抛出异常。

【问题讨论】:

  • 测试类没有任何变量要存储在 .ser 文件中?你有没有在测试类本身初始化它们?您在用于序列化的对象中的值是多少
  • 在序列化清空文件时尝试FileOutputStream file = new FileOutputStream(".../Example.ser",false);
  • 你有在那个路径上生成的 .ser 文件吗?当你没有那个 .ser 文件时,你会得到流损坏的异常
  • @KalaiarasanManimaran 不,如果文件不存在,他会得到FileNotFoundException。您无法从不存在的文件中获取任何类型的流,无论是否损坏。
  • @PabloGallegoFalcón new FileOutputStream(String) 在第二个参数为 false 时等价于 new FileOutputStream(String, boolean)

标签: java serialization exception-handling


【解决方案1】:

如果这是一项学校作业,并且您必须坚持使用 ObjectInputStream / ObjectOutputStream 序列化,请阅读此答案。但是,如果您可以使用任何您想要的序列化格式,那么我建议您使用非二进制格式,例如 JSON。

像 json-io (https://github.com/jdereg/json-io) 之类的库允许您将单行的 Java 数据序列化为人类可读的 JSON 格式:

String json = JsonWriter.objectToJson(root);

并读取序列化的 JSON 数据:

Object root = JsonReader.jsonToJava(json);

能够查看序列化的内容并阅读它在这种调试情况下非常有帮助。大多数现代 IDE 都可以轻松编辑 JSON 数据,还有一些网站,例如:http://www.jsoneditoronline.org/,允许您直接在浏览器中编辑 JSON。

【讨论】:

    【解决方案2】:
    if(file.read()!=-1) //the first time the file will be empty
    

    问题就在这里。您正在读取并丢弃文件的第一个字节,因此以下读取将不同步。去掉它。评论也不对。第一次运行此代码时,该文件将不存在,而不是空的。如果您仍然需要测试零长度文件,只需单独捕获EOFException,因为您只读取一个对象。

    【讨论】:

    • 感谢现在错误消失了,但序列化现在不起作用。似乎当我再次启动程序时,值被覆盖并且旧的值消失了。
    • 您需要为此开始一个新问题。
    • 这里不能回答吗?为什么我必须创建一个新问题
    • 您不应该提出多个问题,当然也不应该在 cmets 中提出新问题。您还应该投票和/或接受您认为有用的答案。它不是论坛,也不是免费的帮助台。
    猜你喜欢
    • 2010-10-25
    • 2017-03-27
    • 1970-01-01
    • 1970-01-01
    • 2023-01-09
    • 2014-04-25
    • 2013-11-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多