XP Java 1.4.x File Read/Write Bug?



  • Hi

    ich hab ein problem mit File IO und java. Das Programm versucht eine Datei beim Start einzulesehn (die datei existiert), läuft aber auf eine FileIOException. Das Programm vermutet, das die Datei nicht existiert und überschreibt diese fälschlicherweise mit einer Defaulteinstellung.

    kann dieses verhalten jamand bestätigen? ( das Dateien nicht geöffnet werden können, obwohl sie auf dem system existieren )

    Die datei wird wie folgt geöffnet:

    BufferedReader in = new BufferedReader ( new InputStreamReader ( new FileInputStream ( file ) ) );
    

    ein

    in.close();
    

    erfolgt jedoch nicht, das Object wird nur dem GC überlassen, damit er es aufräumt. Kann daher der Fehler kommen? das der GC noch ein Object besitzt, das zugriff auf die datei hat und dadurch eine IOException auslöst? (beides lesend)

    OS: vermutlich XP SP2 (bei 3 Fällen sicher)
    JAVA: 1.4

    den Fehler zu beseitigen ist wie Stecknadel im Heuaufen suchen. Ich konnte bisher den Fehler selbst nicht reproduziehen,

    gruss



  • du kannst wohl sehr sicher sein, dass der fehler in deinem programm liegt und nicht in der vm.

    poste doch mal etwas mehr code.
    vielleicht sowas in der art da stehen: filename = "programme\nicht doch"?

    ;p



  • Wenn du meinst das du damit mehr anfangen kannst.

    /*
     * Created on 20.09.2004
     *
     */
    package de...DatabaseIO;
    
    import java.io.BufferedReader;
    
    ...
    
    /**
     * Loder implementation for File IO
     *
     */
    public class FileLoader implements Loader, Serializable
    {
       /**
        * load the data and add it to the accountDatabase
        */
       public void load ( AccountDatabase manager )
       {
    
          File file = new File ( "C:\\rights.txt" );
    
          try
          {
             BufferedReader in = new BufferedReader ( new InputStreamReader ( new FileInputStream ( file ) ) );
    
             String str;
             while ( ( str = in.readLine () ) != null )
             {
                StringTokenizer to = new StringTokenizer ( str, "\t" );
                ...
             }
          }
          catch ( FileNotFoundException e )
          {
             e.printStackTrace ();
          }
          catch ( IOException e )
          {
             e.printStackTrace ();
          }
    
          file = new File ( "C:\\user.txt" );
          try
          {
             BufferedReader in = new BufferedReader ( new InputStreamReader ( new FileInputStream ( file ) ) );
    
             String str;
             while ( ( str = in.readLine () ) != null )
             {
                StringTokenizer to = new StringTokenizer ( str, "\t" );
                ...
             }
          }
          catch ( FileNotFoundException e )
          {
             e.printStackTrace ();
          }
          catch ( IOException e )
          {
             e.printStackTrace ();
          }
    
          file = new File ( "C:\\groups.txt" );
          try
          {
             BufferedReader in = new BufferedReader ( new InputStreamReader ( new FileInputStream ( file ) ) );
    
             String str;
             while ( ( str = in.readLine () ) != null )
             {
                StringTokenizer to = new StringTokenizer ( str, "\t" );
                ...
             }
          }
          catch ( FileNotFoundException e )
          {
             e.printStackTrace ();
          }
          catch ( IOException e )
          {
             e.printStackTrace ();
          }
       }
    
       /**
        * save the data
        */
       public void save ( Group[] groups, User[] users, Right[] rights )
       {
          File file = new File ( "C:\\rights.txt" );
    
          try
          {
             FileWriter out = new FileWriter ( file );
    
             for ( int i = 0; i < rights.length; i++ )
             {
                out.write ( rights[i].toString () );
                out.write ( "\n" );
             }
    
             out.flush ();
             out.close ();
    
             file = new File ( "C:\\groups.txt" );
             out = new FileWriter ( file );
    
             for ( int i = 0; i < groups.length; i++ )
             {
                out.write ( groups[i].toString () );
                out.write ( "\n" );
             }
    
             out.flush ();
             out.close ();
             file = new File ( "C:\\user.txt" );
             out = new FileWriter ( file );
    
             for ( int i = 0; i < users.length; i++ )
             {
                out.write ( users[i].toString () );
                out.write ( "\n" );
             }
             out.flush ();
             out.close ();
          }
          catch ( FileNotFoundException e )
          {
             e.printStackTrace ();
          }
          catch ( IOException e )
          {
             e.printStackTrace ();
          }
       }
    }
    
    und ein teil aus dem manager
    
       Loder dbLoader = new FileLoader (); // wird eigentlich von ausen übergeben
    ...
       private void save ()
       {
          this.data.save ( this.dbLoader );
       }
    
       private void load ()
       {
          this.data.load ( this.dbLoader ); // db laden
    
          try
          {
             if ( this.initAccount != null ) // wenn test vorhanden
             {
                this.initAccount.test ( this.data ); // dann db testen und ggf koriegieren
             }
          }
          catch ( GeneralAccountException e )
          {
             e.printStackTrace ();
          }
    
          save (); // und sichern
       }
    
    ...
    

    Wie man sehen sollte implementiert die Klasse das Interface Loader. Diese wird von der Benutzerverwaltung dazu verwendet die Daten zu speichern und zu laden. (damals war noch eine DB version im gespräch). In this.initAccount.test() wird die datenstruckturüberprüft und ggf fehlende sachen nachgetragen (grundinitalisierung z.B. für den Adminbenutzer)

    gruss

    [nachtrag]
    ich vermute weniger das dafür die vm verantwortlich ist, als das da eher windows XP kleinere probleme hat.



  • hm, also wenn ich das schliessen der datei weglasse, dann landet auch nichts in der datei. liegts vielleicht daran, dass dann versucht wird eine leere datei zu lesen?



  • Du redest hier von 'FileIOException' und IOException, deine 'Vermutung' laesst aber eher auf eine FileNotFoundException schliessen.

    Poste am besten mal den StackTrace und paar dazugehoerige Quelltext-Zeilen.



  • Ist doch nicht wert ausdiskutiert zu werden, solange noch wissentlich der Stream nicht geschlossen wird. Natürlich kann man ihn dann nicht neu aufmachen, wenn er vorhin mit write geöffnet wurde. Ich sehe den Sinn auch gar nicht zu schreiben "Ich benutze den Stream zwar falsch, vermute aber einen Bug in der VM oder mit Windows XP". Erstmal richtig benutzen, d.h. sowas wie try { ... } finally { stream.close(); } und wenn es dann nicht geht, kann man immer noch woanders den Fehler suchen oder einen Bug in der Java-Implementierung vermuten. Und dann steht bei solchen Exceptions meistens ein beschreibender Text dabei wie "access to file bla was denied".



  • Hi

    wenn ich einen stacktrace hätte währe ich eindeutig schlauer. mal schauen ob ich das irgendwie reproduziert bekomme.

    Das Schliessen der streams beim einlesen wird eingefügtt. Nur ob das alleine das problem lösen wird, bezweifle ich.

    Der fehler tritt ja bereits beim öffnen des streams auf. bevor ich vergessen habe diesen zu schliesen.

    Aber danke mal. Ich werd mir nochmal den kopf darüber zerbrechen.

    weis grad jemand zufälliger weise wie java dateien lesend öffnet? Blockierend? so das alle andren versuche auf diese datei zugriff zu erlangen fehlschlagen. oder nicht?

    gruss Termite



  • Windows: Wenn du sie nur zum Lesen öffnest, sollte sie von anderen Anwendungen, die sie auch nur lesend öffnen wollen, noch benutzbar sein. Ist aber natürlich ein bisschen Betriebssystem-abhängig.
    Du musst doch die genaue Exception-Meldung kriegen, oder? Das Öffnen einer Datei kann immer fehlschlagen, ohne dass du es vorher sehen kannst. Das ist der Grund, warum der Java-Compiler dich zwingt, eine IOException zu fangen. An der Stelle, wo du sie fängst, schreib halt in ein logfile oder gib was auf der Konsole aus, zeig ne Nachricht an... 🙂
    Die Exception hat fast immer noch mehr Informationen als den Stack Trace.


Anmelden zum Antworten