wake-up-neo.com

EOFException - wie soll ich damit umgehen?

Ich bin ein Java-Anfänger, der die Java-Tutorials befolgt.

Ich verwende ein einfaches Java-Programm aus der Java-Tutorials 's Data Streams Page , und zur Laufzeit zeigt es weiterhin EOFException an. Ich habe mich gefragt, ob dies normal ist, da der Leser irgendwann das Ende der Datei erreichen muss.

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

Es kompiliert gut, aber die Ausgabe ist:

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.

Aus der Java-Tutorials 's Data Streams-Seite heißt es:

Beachten Sie, dass DataStreams eine Dateiende-Bedingung erkennt, indem Sie EOFException abfangen, anstatt auf einen ungültigen Rückgabewert zu prüfen. Alle Implementierungen von DataInput-Methoden verwenden EOFException anstelle von Rückgabewerten.

Bedeutet das also, dass EOFException abgefangen wird, ist es normal, nur zu fangen und nicht zu handhaben, ist in Ordnung und bedeutet, dass das Ende der Datei erreicht ist?

Wenn es bedeutet, dass ich damit umgehen sollte, teilen Sie mir bitte mit, wie es geht.

EDIT

Von den Vorschlägen habe ich es behoben, indem ich in.available() > 0 für die while-Schleifenbedingung verwende.

Oder ich könnte nichts tun, um die Ausnahme zu behandeln, weil es in Ordnung ist.

18
Jonathan Lam

Während Sie aus der Datei lesen, beenden Sie Ihre Schleife nicht. Also lesen Sie alle Werte und richtig wirft EOFException bei der nächsten Iteration der Lesezeile in der folgenden Zeile ab:

 price = in.readDouble();

Wenn Sie die Dokumentation lesen, heißt es:

Wirft:

EOFException - wenn dieser Eingangsstrom vor dem Lesen von acht Bytes das Ende erreicht.

IOException - Der Stream wurde geschlossen und der enthaltene Eingabestrom unterstützt das Lesen nach dem Schließen nicht oder ein anderer E/A-Fehler tritt auf.

Setzen Sie eine gültige Beendigungsbedingung in Ihre while-Schleife, um das Problem zu lösen, z. unten:

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

Der beste Weg, um damit umzugehen, besteht darin, die Endlosschleife mit einem ordnungsgemäßen Zustand zu beenden.

Aber da haben Sie nach der Ausnahmebehandlung gefragt:

Versuchen Sie, zwei Fänge zu verwenden. Ihre EOFException wird erwartet, daher scheint es kein Problem zu sein, wenn es auftritt. Jede andere Ausnahme sollte behandelt werden.

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

Alternativ können Sie zuerst die Anzahl der Elemente (als Kopfzeile) mit folgendem Befehl ausschreiben:

out.writeInt(prices.length);

Wenn Sie die Datei lesen, lesen Sie zuerst die Kopfzeile (Elementanzahl):

int elementCount = in.readInt();

for (int i = 0; i < elementCount; i++) {
     // read elements
}
2
Katona

Sie können while(in.available() != 0) anstelle von while(true) verwenden.

2
akaHuman

Sie fangen IOException, was auch EOFException abfängt, weil es vererbt wird. Wenn Sie sich das Beispiel aus dem Tutorial anschauen, unterstrichen Sie, dass Sie EOFException abfangen sollten - und dies tun sie auch. Um Ihr Problem zu lösen, fangen Sie EOFException vor IOException:

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

Abgesehen davon mag ich die Datenflusskontrolle nicht mit Ausnahmen - es ist nicht die beabsichtigte Verwendung von Ausnahmen und somit (meiner Meinung nach) wirklich schlechter Stil.

0
Jost

Fügen Sie Ihren Code in den try-catch-Block ein:

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

Möglicherweise stoßen Sie auf Code, der aus einer InputStream liest und das Snippet while(in.available()>0) verwendet, um nach dem Ende des Streams zu suchen, anstatt nach einer EOFException (Ende der Datei) zu suchen.

Das Problem bei dieser Technik, und die Variable Javadoc weist darauf hin, dass nur die Anzahl der Blöcke angegeben wird, die gelesen werden können, ohne den nächsten Aufrufer zu blockieren. Mit anderen Worten, es kann return 0 sein, selbst wenn mehr Bytes gelesen werden müssen. Daher sollte die InputStream available()-Methode niemals zur Überprüfung des Stream-Endes verwendet werden.

Sie müssen while (true) und verwenden

catch(EOFException e) {
//This isn't problem
} catch (Other e) {
//This is problem
}
0
Taleh Alqayev