EOFException – как обращаться?

Я начинающий Java-программист, следуя инструкциям по java .

Я использую простую программу Java на странице streamов данных Java tutorials , и во время выполнения она продолжает показывать EOFException . Мне было интересно, нормально ли это, так как читатель должен в конце концов дойти до конца.

 import java.io.*; public class DataStreams { static final String dataFile = "F://Java//DataStreams//invoicedata.txt"; static final double[] prices = { 19.99, 9.99, 15.99, 3.99, 4.99 }; static final int[] units = { 12, 8, 13, 29, 50 }; static final String[] descs = { "Java T-shirt", "Java Mug", "Duke Juggling Dolls", "Java Pin", "Java Key Chain" }; public static void main(String args[]) { try { DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(dataFile))); for (int i = 0; i < prices.length; i ++) { out.writeDouble(prices[i]); out.writeInt(units[i]); out.writeUTF(descs[i]); } out.close(); } catch(IOException e){ e.printStackTrace(); // used to be System.err.println(); } double price; int unit; String desc; double total = 0.0; try { DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream(dataFile))); while (true) { price = in.readDouble(); unit = in.readInt(); desc = in.readUTF(); System.out.format("You ordered %d" + " units of %s at $%.2f%n", unit, desc, price); total += unit * price; } } catch(IOException e) { e.printStackTrace(); } System.out.format("Your total is %f.%n" , total); } } 

Он компилируется отлично, но выход:

 You ordered 12 units of Java T-shirt at $19.99 You ordered 8 units of Java Mug at $9.99 You ordered 13 units of Duke Juggling Dolls at $15.99 You ordered 29 units of Java Pin at $3.99 You ordered 50 units of Java Key Chain at $4.99 java.io.EOFException at java.io.DataInputStream.readFully(Unknown Source) at java.io.DataInputStream.readLong(Unknown Source) at java.io.DataInputStream.readDouble(Unknown Source) at DataStreams.main(DataStreams.java:39) Your total is 892.880000. 

На странице «Потоки данных Java» в учебниках говорится:

Обратите внимание, что DataStreams обнаруживает условие конца файла, перехватывая EOFException , вместо проверки на недопустимое возвращаемое значение. Все реализации методов DataInput используют EOFException вместо возвращаемых значений.

Итак, означает ли это, что улавливание EOFException является нормальным, так что просто поймать его и не обрабатывать это нормально, а это значит, что конец файла достигнут?

Если это означает, что я должен это обработать, пожалуйста, сообщите мне, как это сделать.

РЕДАКТИРОВАТЬ

Из предложений я исправил его, используя in.available() > 0 для условия цикла while.

Или я не мог ничего сделать, чтобы справиться с этим исключением, потому что все в порядке.

Во время чтения из файла вы не завершаете свой цикл. Таким образом, он считывает все значения и корректно выбрасывает EOFException на следующей итерации строки ниже:

  price = in.readDouble(); 

Если вы прочтете документацию, в нем говорится:

Броски:

EOFException – если этот входной stream достигает конца перед чтением восьми байтов.

IOException – stream был закрыт, а входящий stream не поддерживает чтение после закрытия или возникла другая ошибка ввода-вывода.

Поставьте правильное условие завершения в цикл while, чтобы решить проблему, например, ниже:

  while(in.available() > 0) <--- if there are still bytes to read 

Лучшим способом справиться с этим было бы прекращение вашего бесконечного цикла с надлежащим условием.

Но так как вы попросили об обработке исключений:

Попробуйте использовать два улова. Ожидается ваше EOFException, поэтому, кажется, нет проблем, когда это происходит. Любое другое исключение должно быть обработано.

 ... } catch (EOFException e) { // ... this is fine } catch(IOException e) { // handle exception which is not expected e.printStackTrace(); } 

Вы можете использовать while(in.available() != 0) вместо while(true) .

Кроме того, вы можете записать количество элементов сначала (в виде заголовка), используя:

 out.writeInt(prices.length); 

Когда вы читаете файл, вы сначала читаете заголовок (количество элементов):

 int elementCount = in.readInt(); for (int i = 0; i < elementCount; i++) { // read elements } 

Вы улавливаете IOException которое также ловит EOFException , потому что оно унаследовано. Если вы посмотрите на пример из учебника, они подчеркнули, что вы должны поймать EOFException – и это то, что они делают. Чтобы решить вашу проблему, перехватите EOFException перед IOException :

 try { //... } catch(EOFException e) { //eof - no error in this case } catch(IOException e) { //something went wrong e.printStackTrace(); } 

Кроме того, мне не нравится управление streamом данных с использованием исключений – это не намеренное использование исключений и, следовательно, (на мой взгляд) действительно плохой стиль.

Поместите свой код внутри блока catch try: ie:

 try{ if(in.available()!=0){ // ------ } }catch(EOFException eof){ // }catch(Exception e){ // } } 
  • Прояснение с помощью try-catch-finally-return
  • Проблема с «областями» переменных в блоках catch try в Java
  • Как я могу предотвратить сбой node.js? try-catch не работает
  • исключения try-catch в Swift
  • Эквивалент Try-with-resources в Java 1.6
  • Почему блок Try / Catch создает новую область переменных?
  • Почему я не должен обертывать каждый блок в «try» - «catch»?
  • Каковы обстоятельства, при которых блок finally {} не будет выполняться?
  • C # поймать исключение переполнения стека
  • catch исключение указателем в C ++
  • Зачем ловить и реконструировать исключение в C #?
  • Interesting Posts

    Самый эффективный способ использования замены нескольких слов в строке

    Как сжать файлы VHD Windows 7 XP Mode?

    Панель действий Android, не отображающая переполнение

    Должен ли разработчик ориентироваться на читаемость или производительность?

    Получить только имя файла из пути в сценарии Bash

    Эта версия приложения не настроена для выставления счетов через Google Play

    SyntaxError: использование const в строгом режиме?

    Где я могу найти список URL-адресов поставщика OpenID?

    Обнаружение обнаружения записи

    Разрешения ServiceController в Windows 7

    В Windows 8 или 10, особенно на планшетах с постоянно вставленной SD-картой, существует ли универсальный способ обработки карты как несъемного диска?

    Каков самый элегантный способ чтения текстового файла с помощью c ++?

    Facebook Graph Api – Проводка на страницу поклонников в качестве администратора

    Какие режимы программной рейды поддерживает каждая версия Windows 7?

    Какова цель символа «@» в CSS?

    Давайте будем гением компьютера.