为什么我会得到java.io.EOFException?

为什么我会得到java.io.EOFException?,java,exception,eof,Java,Exception,Eof,这是一种从包含show类型的序列化对象的.ser文件中读取show详细信息的方法。该方法已成功返回列表,但在此之前出现异常。为什么会这样?我如何摆脱它 public List<Show> populateDataFromFile(String fileName) { List<Show> shows=new ArrayList<Show>(); ObjectInputStream obj=null; try {

这是一种从包含show类型的序列化对象的.ser文件中读取show详细信息的方法。该方法已成功返回列表,但在此之前出现异常。为什么会这样?我如何摆脱它

public List<Show> populateDataFromFile(String fileName) {
        List<Show> shows=new ArrayList<Show>();
        ObjectInputStream obj=null;
    try {
        FileInputStream fin=new FileInputStream(fileName);
        obj=new ObjectInputStream(fin);
        Show show=null;
        while((show=(Show) obj.readObject())!=null)
        {
            shows.add(show);
            show.getShowName();
        }
        System.out.println(shows);
    } catch (IOException e) {
        e.printStackTrace();
    }catch(ClassNotFoundException e)
    {
        e.printStackTrace();
    }finally
    {
        try {
            obj.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    return shows;
}
主要方法是

public static void main(String[] args) {
    DataManager dm=new DataManagerImpl();
    List<Show>shows=dm.populateDataFromFile("ShowDetails.ser");
    // Call all the functionalities from here to test your code.    
    for(Show show:shows)
    {
        System.out.println("Show Name: "+show.getShowName());
        System.out.println("Show Time: "+show.getShowTime());
        System.out.println("Seats Available: "+show.getSeatsAvailable());
    }
}
publicstaticvoidmain(字符串[]args){
DataManager dm=新的DataManagerImpl();
Listshows=dm.populateDataFromFile(“ShowDetails.ser”);
//从这里调用所有功能来测试代码。
用于(显示:显示)
{
System.out.println(“显示名称:+Show.getShowName());
System.out.println(“显示时间:+Show.getShowTime());
System.out.println(“可用座位:+show.getSeatsAvailable());
}
}

因为您已到达文件末尾

您似乎认为readObject()在文件末尾返回null。没有。当且仅当您编写null时,它返回null


正确的测试是捕获EOFEException和break,在readObject()返回null之前不读取。

,因为您已经到达了文件的末尾

您似乎认为readObject()在文件末尾返回null。没有。当且仅当您编写null时,它返回null


正确的测试是捕获EOFEException和break,在readObject()返回null之前不读取。

EJP正确地认为,发生错误是因为当文件中没有更多显示时,方法
readObject()
不返回null

EJP还提出了一个解决方案。我只是想建议几个其他的解决方案,但是这些解决方案不是修复读取文件的代码,而是修复写入文件的代码

当前,该文件是通过多次调用
writeObject()
方法生成的,每个方法都有一个
Show
对象。您可以:

  • 创建一个包含显示的
    列表
    对象。将此
    列表
    写入文件。当您读取此文件时,您可以将
    列表
    读回。您不必使用while循环,因此可以避免EOF异常检查

  • 首先将放映次数写入文件。然后,将节目逐一写入文件。读取文件时,需要首先读取节目数,这将通知您要从文件中读取多少个节目。这将避免EOF异常检查


  • EJP认为发生错误是正确的,因为当文件中不再显示时,方法
    readObject()
    不会返回NULL

    EJP还提出了一个解决方案。我只是想建议几个其他的解决方案,但是这些解决方案不是修复读取文件的代码,而是修复写入文件的代码

    当前,该文件是通过多次调用
    writeObject()
    方法生成的,每个方法都有一个
    Show
    对象。您可以:

  • 创建一个包含显示的
    列表
    对象。将此
    列表
    写入文件。当您读取此文件时,您可以将
    列表
    读回。您不必使用while循环,因此可以避免EOF异常检查

  • 首先将放映次数写入文件。然后,将节目逐一写入文件。读取文件时,需要首先读取节目数,这将通知您要从文件中读取多少个节目。这将避免EOF异常检查


  • 无论如何都会返回该列表,因为捕获到异常,因此不会停止方法的执行,而是正常返回。现在,如果一些数据被添加到列表中,那么这些数据将被返回,这是有意义的,但即使在去掉finally块并关闭streams之后,我也会得到相同的错误。不管怎样,列表都会被返回,因为异常被捕获,因此不会停止方法的执行,它会正常返回。现在,如果一些数据被添加到列表中,这些数据将被返回,这是有意义的,但是即使在去掉finally块并在while循环之后关闭流,我也会得到相同的错误。你的意思是我可以使用while(1)这样的条件并在循环内部进行反序列化吗?如果是的话。你能举个例子吗?你自己刚刚举了个例子。这并不难。你的意思是我可以使用while(1)这样的条件来进行反序列化内部循环吗?如果是的话。你能举个例子吗?你自己刚刚举了个例子。这并不难。它无法避免EOFEException检查。无法保证写入过程实际写入了标头计数指定的对象数。它本可以写得更少,然后被中断,或者以某种方式失败。它甚至可以写得更多。您仍然必须处理EOFEException。@这是正确的。我假设文件是完整的。也就是说,可以毫无问题地编写文件。如果不这样假设,我们可能会得到其他异常,而不仅仅是EOFEException。它无法避免EOFEException检查。无法保证写入过程实际写入了标头计数指定的对象数。它本可以写得更少,然后被中断,或者以某种方式失败。它甚至可以写得更多。您仍然必须处理EOFEException。@这是正确的。我假设文件是完整的。也就是说,可以毫无问题地编写文件。如果不这样假设,我们可能会得到其他异常,而不仅仅是EOFEException。
    public static void main(String[] args) {
        DataManager dm=new DataManagerImpl();
        List<Show>shows=dm.populateDataFromFile("ShowDetails.ser");
        // Call all the functionalities from here to test your code.    
        for(Show show:shows)
        {
            System.out.println("Show Name: "+show.getShowName());
            System.out.println("Show Time: "+show.getShowTime());
            System.out.println("Seats Available: "+show.getSeatsAvailable());
        }
    }