eofexception – Hoe omgaat?

Ik ben een beginners Java-programmeur na de Java-tutorials .

Ik gebruik een eenvoudig Java-programma van de Java-tutorials ‘s Data-streams pagina , en bij runtime blijft het met EOFException. Ik vroeg me af of dit normaal was, omdat de lezer uiteindelijk uiteindelijk naar het einde van het bestand moet komen.

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

Het compileert prima, maar de uitvoer is:

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.

Van de Java-tutorials‘s Datastreams-pagina, staat er:

Merk op dat DataStreams een end-of-file-conditie detecteert door EOFException, in plaats van te testen op een ongeldige retourwaarde. Alle implementaties van DataInput-methoden gebruiken EOFException in plaats van retourwaarden.

Betekent dit dat het vangen van EOFExceptionnormaal is, dus het gewoon vangen en niet afhandelen is prima, wat betekent dat het einde van het bestand is bereikt?

Als dit betekent dat ik het moet aanpakken, geef me dan alsjeblieft advies over hoe ik het moet doen.

bewerken

Van de suggesties, ik heb het gerepareerd met behulp van in.available() > 0voor de whileloopconditie.

Of, ik zou niets kunnen doen om de uitzondering af te handelen, omdat het goed is.


Antwoord 1, Autoriteit 100%

Tijdens het lezen van het bestand is uw lus niet beëindigen. Dus het leest alle waarden en correct gooit EOFEXCeption op de volgende iteratie van de lees op regel hieronder:

price = in.readDouble();

Als u de documentatie leest, zegt het:

Thoei:

Eofexception – Als deze ingangsstroom het einde bereikt voordat u acht bytes leest.

IOException – De stroom is gesloten en de ingesloten ingangsstroom ondersteunt geen lezing na dichtbij, of een andere I / O-fout treedt op.

Zet een juiste beëindigingsconditie in uw tijdje om het probleem op te lossen b.v. hieronder:

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

Antwoord 2, Autoriteit 30%

De beste manier om dit aan te pakken zou zijn om uw oneindige lus met een goede staat te beëindigen.

Maar aangezien u om de uitzonderingsbehandeling heeft gevraagd:

Probeer twee vangsten te gebruiken. Uw EOFEXCEPTIE wordt verwacht, dus er lijkt geen probleem te zijn wanneer het voorkomt. Elke andere uitzondering moet worden afgehandeld.

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

Antwoord 3, Autoriteit 9%

U kunt while(in.available() != 0)in plaats van while(true).


Antwoord 4, Autoriteit 9%

U kunt ook het aantal elementen eerst (als koptekst) ophalen met:

out.writeInt(prices.length);

Wanneer u het bestand leest, leest u eerst de kop (element Count):

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

Antwoord 5, Autoriteit 9%

U kunt code tegenkomen die leest van een InputStreamen gebruikt het fragment
while(in.available()>0)om te controleren op het einde van de stroom, in plaats van te controleren op een
Eofexception (einde van het bestand).

Het probleem met deze techniek, en de Javadocdoet Echo dit, is dat het alleen het aantal blokken vertelt dat kan worden gelezen zonder de volgende beller te blokkeren. Met andere woorden, het kan return 0zelfs als er meer bytes moeten worden gelezen. Daarom mag de InputStream available()-methode nooit worden gebruikt om te controleren op het einde van de stroom.

U moet while (true)en

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

Antwoord 6

u vangt IOExceptiondie ook vangt EOFException, omdat deze wordt geërfd. Als u naar het voorbeeld kijkt uit de tutorial ze onderstreepte dat u zou moeten vangen EOFException– en dit is wat ze doen. Om u op te lossen Probleem Catch EOFExceptionVóór IOException:

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

Bovendien houd ik niet van datastroombeheer met uitzonderingen – het is niet het beoogde gebruik van uitzonderingen en dus (naar mijn mening) echt slechte stijl.


Antwoord 7

Plaats je code in het try-catch-blok:
dat wil zeggen:

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

Antwoord 8

EOFException is een kind van IOException
Ik geef er de voorkeur aan zoals hieronder ==>

try {
        .
        .
        .
    } catch (IOException e) {
        if (!(e instanceof EOFException)) {
            throw new RuntimeException(e);
        }
    }

Other episodes