EOFException при чтении файлов с ObjectInputStream

У меня в основном такая же проблема, как указано здесь: EOFexception в Java при чтении objectinputstream, но я не могу найти ответ с чистым кодом.

Ответ гласит, что ObjectInputStream#readObject выдаст исключение, когда читатель достигнет конца файла. После поиска решения в Интернете я не нашел решения. Может ли быть хорошим и чистым решением для этого случая?

Примечание: я пробовал это (но это выглядит некрасиво и не чистый код). Я ищу лучшее решение:

ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
try {
    Object o;
    while ((o = ois.readObject()) != null) {
        if (o instanceof MyClass) {
            MyClass m = (MyClass)o;
            //use the object...
        }
    }
} catch (EOFException eofex) {
    //do nothing
}  catch (IOException ioex) {
    throw ioex;
    //I have another try/catch block outside to control the life of the ObjectInputStream
}
//later in the code...
ois.close();

4 ответа

Решение

Вот что должно было случиться. Ваш код неверен. Проверьте Javadoc. readObject() только возвращается null если вы написали null, Это ничего не говорит о возврате ноля в EOF. Цикл до readObject() возвращается null остановится, только если вы когда-нибудь написали null с помощью writeObject()и если вы этого не сделаете, вы получите EOFException,

@EJP ответ прибил его.

Однако, если вы являетесь оплаченным членом клуба "исключения не должны использоваться для нормального управления потоком" *, вы можете избежать необходимости ловить исключение, если можете использовать другие средства для определения того, когда следует остановиться; например

  • Вы можете начать поток со счетчика, отправленного как int или Integer объект.
  • Вы можете отметить конец потока, отправив null,
  • Вы можете пометить конец потока, отправив специальный объект, который означает "это конец". Это не должно быть MyClass пример.
  • Вы можете отправить List<MyClass>... хотя это означает, что вы не можете "поток" объектов.

Обратите внимание, что это означает, что вы можете изменить код на стороне отправителя...


* Членство в этом клубе требует либо умения усваивать круглые аргументы, либо готовности слепо принять догму как истину. :-)


Вместо того, чтобы повторять аргументы до тошноты, вот несколько ссылок на некоторые из моих ответов, связанных с дебатами о "нормальном управлении потоком":

Если вы прочитаете их, вы увидите, что я не спускаюсь твердо по обе стороны забора. Скорее, я считаю, что вы должны понимать компромиссы и принимать решение о том, являются ли исключения уместными или нет в каждом конкретном случае.

Вы можете попробовать это:

boolean check=true;
while (check) {
   try{
       System.out.println(ois.readObject());
   } catch(EOFException ex){
       check=false;
   }
}

Я столкнулся с этой ошибкой, потому что забыл закрыть ObjectOutputStream в коде, который записал данные. Как только я снова записал данные с помощью кода, закрывающего выходной поток, данные можно было нормально прочитать.

В то время как readObject() не возвращается NULL когда он достигает конца файла, если вы контролируете файл с самого начала, вы всегда можете добавить NULL прямо перед закрытием вашего выходного потока. Он будет передан как объект, но вы можете проверить конец файла как таковой:

Boolean complete = false;
ObjectInputStream in = <...>

while(complete != true) {
    Object test = (Object)in.readObject();
    if(test != null) { someArrayList.add(test); }
        else { complete = true; }
}
Другие вопросы по тегам