Java

Guin

Registered User
Hallo Leute.
Ich bin gezwungen mich nun mit Java auseinander zu setzen.

Hier eine Schilderung fuer Java Experten.

Bei einem kleinen Test ist mir etwas mir nicht verstaendliches aufgefallen.

Hier das Skript (es soll das Eingegebene [3 Techniken] wieder ausgeben)
Code:
import java.io.* ;
/**
 * Class Eingabe
 * Dateiname: Eingabe.java
 * @version 1.00, 21.03.2007
 *
 */

public class Eingabe
{
       /** Methode main startet das Programm. Es es werden insgesamt
       * drei Eingaben erwartet.
       *@Param String[] args Übergabeparameter des Programmaufrufs
       */
  public static void main(String[] args)   throws IOException
  {      // wir leiten die Exception einfach
         //nach oben weiter, nicht unser Problem
         
    /** Variable enthaelt den Integerwert des eingegebenen Zeichens
    * bei Einbae 1 und Eingabe 2.*/
    int i=32;
    /** Variable enthaelt den String der dritten Eingabe.*/
    String expr = new String();
// 1. Eingabe
    System.out.print("\nEingabe bitte: ");
    i=System.in.read();
    System.in.skip(System.in.available());
    System.out.println(" Char: "+ (char)i +
                 "\n Eingabetechnik: System.in.read() OHNE Ausnahmebehandlung");
// 2. Eingabe
    System.out.print("\n\nEingabe bitte: ");
    try{        // versuch doch mal, ob's klappt
    i=System.in.read();     // zweite Eingabe: Einzelzeichen
    System.in.skip(System.in.available());   // Eingabespeicher leeren
    } // try
    catch (java.io.IOException e){
    System.err.println("Eingabefehler: "+e.toString());
    } // catch (java.io.IOException)
    System.out.println(" Char: "+ (char)i +
                "\n Eingabetechnik: System.in.read() MIT Ausnahmebehandlung");
// 3. Eingabe
    BufferedReader In = new BufferedReader (new InputStreamReader (System.in));

    System.out.print ("\nEingabe: ");
    expr = In.readLine();
    System.out.println(" String: "+ expr +"\n Eingabetechnik: BufferedReader");
  }// main(String[] args)
} // public class Eingabe
Um den Eingabepuffer zu "leeren" verwende ich skip()
"System.in.skip(System.in.available());"
Mit dieser Methode (mit available() ) kommt es zu keiner Exception wenn ich als Eingabe ^Z ([strg]+z) taetige.
Wenn ich
System.in.skip(200);
benutze, dann kommt es zu einer Exception.

Woran liegt dieser Unterschied?
Win XP SP2, Java 1.6

Gruss
Guin
 
Last edited by a moderator:
Also ich bekomme keine Exception (Java 1.5) bei Strg-Z. Auch eine Pipe mit 0 Bytes liefert keine.
Aber evtl. solltest Du auch die Exception mal genauer untersuchen: Nicht mit e.toString() sondern mit e.printStackTrace().
Ich denke sie kommt nämlich vom read(). Und bei einem skip(200) ist logisch, daß er eine Exception wirft wenn keine 200 Bytes im Buffer liegen.

Wie immer stellt sich mir die Frage: Was ist das eigentliche Problem?

huschi.
 
Und bei einem skip(200) ist logisch, daß er eine Exception wirft wenn keine 200 Bytes im Buffer liegen.
So ganz logisch ist das nicht. skip() soll bis zu 200 Zeichen ueberspringen. Wenn das Ende vorher kommt, ist auch gut (wenn man nur "a" eingibt, kommt auch kein Fehler).

skip soll Zeichen fuer zeichen vorspringen, bis die angegebene Anzahl erreicht ist, oder der String zu ende ist.
available soll eigentlich aehnlich vorgehen. Auch Zeichen fuer Zeichen vorspringen und die Zeichen zaehlen. Am Stringende wieder zum Anfang springen und die Anzahl zurueckgeben.

Ein Zeichen hat in Java (wegen dem unicode) 2 Byte. Von daher sollte man Zeichen und Byte nicht vermischen.

Wenn ich daneben liege, moege man mich berichtigen.

Mal auf das Wesentliche gekuerzt.
Code:
import java.io.* ;
public class Eingabe2
{
  public static void main(String[] args)   throws IOException
  {
    int i=32;
    System.out.print("\n\nEingabe bitte: ");
    try{
    i=System.in.read();
    System.in.skip(255);
    }
    catch (java.io.IOException e){
    System.err.println("Eingabefehler: "+e.toString()+"\n");
    e.printStackTrace();
    }
    System.out.println(" Char: "+ (char)i +
                "\n Eingabetechnik: System.in.read() MIT Ausnahmebehandlung");
  }// main(String[] args)
} // public class Eingabe

Wie immer stellt sich mir die Frage: Was ist das eigentliche Problem?
:(
Studium zweite Stunde Java war genau das oben genannte Skript gefordert. Eigentlich gibt es kein Problem. Die Aufgabe ist geloest. Nur ist mir halt aufgefallen, dass bei ^Z ein Fehler kommt (siehe Anhang). Mein Mentor konnte mir darauf auch keine Antwort geben, also muss ich andere Quellen befragen.
 

Attachments

  • ou01.png
    ou01.png
    3.6 KB · Views: 109
Also wenn Du es schon genau nimmst, dann sprich auch vom Stream und nicht von Strings. Ein Stream kann eine endliche als auch endlose Folge von Bytes sein. (In meinem SDK ist im InputStream auch explizit nur von Bytes die Rede.)
Ein String ist immer eine endliche Folge von Zeichen mit einem Terminator (0).
Dies ist spätestens bei der Codierung ein deutlicher Unterschied.

available soll eigentlich aehnlich vorgehen.
Nö. Während skip() den Buffer nachladen würde, steht davon im available() nichts. Im Gegenteil: available() gibt nur die aktuelle Anzahl Bytes im Buffer zurück.

Nur ist mir halt aufgefallen, dass bei ^Z ein Fehler kommt (siehe Anhang).
Evlt. ist es auch ne Frage des Handlers. Dein StackTrace zeigt ja, daß der Fehler im FileInputStream.skip() erzeugt wird. Eine Übelegung wäre z.B.: Kann man einen Keyboard-InputStream dann überhaupt skippen? Es klingt zumindest so, als ob der FileHandle dies zumindest nicht mit machen will.
Versuch es doch mal mit einem echten FileHandle.

huschi.
 
Also wenn Du es schon genau nimmst, dann sprich auch vom Stream und nicht von Strings.
Hast recht. :)
Aber sobald ich return druekce, liegt das Ganze als String vor.

Eine Übelegung wäre z.B.: Kann man einen Keyboard-InputStream dann überhaupt skippen?
Solange kein ^Z ("null") am Anfang steht macht das skip keine Probleme.

Danke.
Mit deinen Informationen werde ich Ende der Woche mal meinen Mentor belaestigen. Mal schaun, ob ihm dann mehr einfaellt.

Versuch es doch mal mit einem echten FileHandle.
Bufferreader macht keine Probleme.
 
Aber sobald ich return druekce, liegt das Ganze als String vor.
Nein, das stimmt nicht. Return setzt hierbei lediglich die Buffer-Mechanismen der verschiedenen Streams in Gange. Und es bleibt ein Stream (Menge an Bytes in nicht voraussagbarer Geschwindigkeit hintereinander eintreffend) bis Du es zu einem String verarbeitest

Solange kein ^Z ("null") am Anfang steht macht das skip keine Probleme.
Ach, die Erklärung liegt doch eigentlich ganz einfach! (Warum bin ich nicht direkt drauf gekommen... :confused: )
^Z (== EOF) schließt den Stream. read() ließt dieses Byte/Zeichen noch. Ein available() liefert natürlich 0 weil Stream geschlossen. Die Kombination skip(available()) tut in dem Fall also auch nix. Liefert also auch keinen Fehler. Ein skip(200) auf einem geschlossenen Stream muß hingegen einen Fehler auswerfen.

Warum es in meinem SDK1.5 anders läuft weiß ich nicht. Evtl. wird hier der InputStream nicht automatisch durch ein ^Z geschlossen.

huschi.
 
^Z (== EOF) schließt den Stream. read() ließt dieses Byte/Zeichen noch. Ein available() liefert natürlich 0...
Super! Klingt zumindest fuer mich einleuchtend :)
 
Back
Top