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>
... хотя это означает, что вы не можете "поток" объектов.
Обратите внимание, что это означает, что вы можете изменить код на стороне отправителя...
* Членство в этом клубе требует либо умения усваивать круглые аргументы, либо готовности слепо принять догму как истину. :-)
Вместо того, чтобы повторять аргументы до тошноты, вот несколько ссылок на некоторые из моих ответов, связанных с дебатами о "нормальном управлении потоком":
- Стоимость соединения, если / или по сравнению с try/catch в Java 6
- Что является альтернативой исключениям для управления потоком?
- Regex или обработка исключений?
- Проверьте, существует ли файл перед вызовом openFileInput
- Что быстрее, попробуйте catch или if-else в java (производительность WRT)
Если вы прочитаете их, вы увидите, что я не спускаюсь твердо по обе стороны забора. Скорее, я считаю, что вы должны понимать компромиссы и принимать решение о том, являются ли исключения уместными или нет в каждом конкретном случае.
Вы можете попробовать это:
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; }
}