EOFException – como lidar?

Eu sou um programador java iniciante seguindo os tutoriais java .

Eu estou usando um programa Java simples da página de streams de dados de tutoriais Java e, em tempo de execução, ele continua mostrando EOFException . Eu queria saber se isso era normal, já que o leitor tem que chegar ao final do arquivo eventualmente.

 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); } } 

Ele compila bem, mas a saída é:

 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. 

Da Página de Fluxos de Dados dos tutoriais Java , ele diz:

Observe que o DataStreams detecta uma condição de fim de arquivo capturando EOFException , em vez de testar um valor de retorno inválido. Todas as implementações de methods DataInput usam EOFException em vez de valores de retorno.

Então, isso significa que pegar EOFException é normal, então apenas pegá-lo e não manipulá-lo é bom, o que significa que o fim do arquivo é atingido?

Se isso significa que eu deveria lidar com isso, por favor me avise sobre como fazer isso.

EDITAR

Das sugestões, in.available() > 0 usando in.available() > 0 para a condição de loop while.

Ou, eu não poderia fazer nada para lidar com a exceção, porque está tudo bem.

Ao ler o arquivo, você não está encerrando o loop. Então, ele lê todos os valores e lança corretamente EOFException na próxima iteração da leitura na linha abaixo:

  price = in.readDouble(); 

Se você ler a documentação, ele diz:

Lança:

EOFException – se este stream de input atingir o final antes de ler oito bytes.

IOException – o stream foi fechado e o stream de input contido não suporta leitura após o fechamento ou ocorre outro erro de E / S.

Coloque uma condição de terminação adequada no seu loop while para resolver o problema, por exemplo, abaixo:

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

A melhor maneira de lidar com isso seria finalizar seu loop infinito com uma condição adequada.

Mas desde que você pediu o tratamento de exceções:

Tente usar duas capturas. Seu EOFException é esperado, portanto, parece não haver nenhum problema quando ocorrer. Qualquer outra exceção deve ser tratada.

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

Você pode usar while(in.available() != 0) vez de while(true) .

Alternativamente, você poderia escrever o número de elementos primeiro (como header) usando:

 out.writeInt(prices.length); 

Quando você lê o arquivo, primeiro lê o header (contagem de elementos):

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

Você captura IOException que também captura EOFException , porque é herdada. Se você olhar o exemplo do tutorial, eles sublinharam que você deve pegar o EOFException – e é isso que eles fazem. Para resolver o problema, capture EOFException antes de IOException :

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

Além disso, eu não gosto de controle de stream de dados usando exceções – não é o uso pretendido de exceções e, portanto, (na minha opinião) estilo muito ruim.

Coloque o seu código dentro do bloco try catch: ie:

 try{ if(in.available()!=0){ // ------ } }catch(EOFException eof){ // }catch(Exception e){ // } }