Array in Datei und zurück



  • Guten Abend.
    Ist stehe vor folgendem Problem:
    Ich möchte ein 2-Dimensionales int Array in eine Datei schreiben und auch umgekehrt ein Datei öffnen und die zahlen in ein Array schreiben.

    Eine Datei zu schreiben hat eigentlich auch ganz gut geklappt(denke ich^^):

    public static void schreiben(int array[][]){
    
    	        // File anlegen
    	         file = new File("test2.txt");
    	         try {
    
    	           writer = new FileWriter(file);
    
    	           //Array in Datei lesen
    		   for(int reihe = 0; reihe < array.length; reihe++){
    
    		    	for(int zeile = 0; zeile < array.length; zeile++){
    
    		    			// Text wird in den Stream geschrieben
    		    			writer.write((int)(array[reihe][zeile]) + " ");
    
    		    		}
    		    		writer.write(";");
    		    		writer.write(System.getProperty("line.separator"));
    		    	}
    	           // Schreibt den Stream in die Datei
    	           // Sollte immer am Ende ausgeführt werden, sodass der Stream 
    	           // leer ist und alles in der Datei steht.
    	           writer.flush();
    
    	           // Schließt den Stream
    	           writer.close();
    	        } catch (IOException e) {
    	          e.printStackTrace();
    	        }
    	      }
    

    Klappt soweit.
    Da druch bekomme ich eine Datei mit folgendem Aufbau:

    0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ;
    0 0 0 0 1 2 2 2 2 2 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ;
    0 0 0 0 1 2 3 3 3 2 2 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ;
    0 0 0 0 1 2 2 3 3 3 2 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ;
    0 0 0 0 1 1 2 3 3 3 2 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ;

    Jedoch schaffe ich es leider nicht eine solche Datei zu öffnen und in ein Array zu schreiben.

    Mein Lösungsansatz:

    public int[][] open() {
    	    	int feld[][] = null;
    
    	    	try {
    	    	      BufferedReader br = new BufferedReader(new FileReader("testdatei.txt"));
    	    	      String zeile = null;
    	    	      int reihe = 0;
    	    	      int zeilen = 0;
    	    	      int i = 0;
    
    	    	      try {
    
    	    	    	  while ((zeile = br.readLine()) != null) {
                                      zeilen++;
    	    	    		  while(zeile !=null){
    	    	    			  feld[zeilen][reihe]= zeile.charAt(reihe);
    	    	    			  reihe++;
    
    	    	    			  System.out.println();
    	    	    		  }
    
    	    	          i++;
    	    	        }
    	    	      } catch (IOException e) {
    	    	        e.printStackTrace();
    	    	      }
    	    	    } catch (FileNotFoundException e1) {
    	    	      e1.printStackTrace();
    	    	    }
    
    	    	return feld;
    	    }
    

    Ich weiß nicht genau was alles falsch ist, jedoch bekomme ich die Fehlermeldung dass ich das Array überschreite.

    Vielleicht wisst ihr ja wie man diese Problem lösen kann oder was ich falsch gemacht habe. Danke für jede Hilfe 🙂



  • Das Problem liegt (hab nicht geschaut obs noch andere hat) in Zeile 2 und 18. Du versuchst da einem Array, das null ist, einen Wert zuzuweisen. Das kann nicht gut gehen. Initialisiere das Array entweder mit einer bestimmten Groesse oder wenn du die Groesse nicht kennst. dann verwende ein dynamisches Array (z.B. ArrayList).



  • Das ist eine tolle Knobelaufgabe! 😃 Ich zähle 6 7 Bugs.

    Kann es sein, dass du zwei unterschiedliche Dateien bearbeitest? Du schreibst in test2.txt und ließt aus testdatei.txt .

    Ich hätte eher mit einer NullPointerException gerechnet. Deine Ausnahme ( IndexOutOfBoundsException ) sollte nur auftreten, wenn die erste Zeile der Datei leer ist und zwar in Zeile 18.

    Schaue dir bitte die Zeile 17 und die Variablen feld , reihe (du meinst wohl Spalte) an.

    Außerdem beachstest du nicht, dass Leerzeichen in jeder Zeile sind, und dass "1".charAt(0) == 49 ist. Wobei dies zu Problemen führen kann, wenn du Werte größer als 9 hast, da du jedes Zeichen einzeln bertachtest.

    [code][quote]0. unterschiedliche Dateinamen. kein Bug in der Funktion

    1. [c]IndexOutOfBoundsException[/c] in Zeile [c]18[/c], bei Leerzeile, da charAt(0) bei "" diese Ausnahme wirft.
    2. ebenso [c]NullPointerException[/c], da [c]feld[/c] nicht initialisert.
    3. Endlosschleife durch die Bedingung in Zeile [c]17[/c]
    4. ebenfalls [c]IndexOutOfBoundsException[/c]in Zeile [c]18[/c], da reihe++ niemals zurückgesetzt wird und irgendwann garantiert [c]reihe[/c] größer wird als [c]zeile[/c] lang.
    5. "1".char(0) == 49 --- (1 + " ") == "1 ", CharAt liefert ASCII zurück.
    6. Spaces im Eingabestream werden eingelesen.
    -1. Die Formatierung wird nicht überprüft. NOCH nicht wichtig[c][/c][/quote][/code]

    Edit: Layout zerschossen
    Edit: Siebter Bug: zeile++; zuerst inkrementiert. Also erste Zeile im Feld immer leer.



  • Vielleicht noch etwas allgemeines:
    Du kannst mehrere Catch-Klauseln hintereinanderschreiben, als in etwa

    try {
    // Mach was
    }
    catch(...) { ... }
    catch(...) { ... }
    

    dann muss du nicht mehrere try-Bloecke schachteln (ist etwas unschoen).

    Dabei ist bloss darauf zu achten, dass je hoeher eine Exception in der Vererbunshierarchie ist, desto spaeter die Catch-Klausel kommen soll.



  • Okay danke schon mal für die Hinweise, jedoch bekomme ich es einfach nicht hin.

    Ich habe zwar ein paar Sachen geändert :

    int feldopen[][] = new int[32][32];
    feldopen[reihe][spalte] = line.charAt(reihe) - 48;
    

    Jedoch klappt es gar leider gar nicht. Ist mein Ansatz überhaupt richtig oder bin ich total auf dem falschem Weg?

    MfG



  • DrunkenMastered schrieb:

    Okay danke schon mal für die Hinweise, jedoch bekomme ich es einfach nicht hin.

    Ich habe zwar ein paar Sachen geändert :

    int feldopen[][] = new int[32][32];
    feldopen[reihe][spalte] = line.charAt(reihe) - 48;
    

    Jedoch klappt es gar leider gar nicht. Ist mein Ansatz überhaupt richtig oder bin ich total auf dem falschem Weg?

    MfG

    Erster vielliecht, wenn die Größe immer konstant ist.

    Ich würde dein Format so abwandeln, sodass das in der ersten Zeile die Breite und in der zweiten die Höhe steht und danach erst deine Daten, sodass du zuerst die ersten beiden Zeilen einließt und davon das Array erstellst.

    Beim zweiten wäre es besser Scanner zu nehmen um die Zahlen auszulesen und gleichzeitig in Zahlen umzuwandeln.



  • soooo...

    gucken wir uns ma deinen code an:

    BufferedReader br = new BufferedReader(new FileReader("testdatei.txt"));
    String zeile = null;
    int reihe = 0;
    int zeilen = 0;
    int i = 0;
    

    Ist ok alle Variablen an einer Stelle zu deklarieren... aber überleg ma, welche du da verwendest:

    zeile: ok...
    zeilen: Is klar..
    reihe: auch klar... obwohl du dir da ma gedanken zur Nomenklatur machen solltest: Für den String verwendest du die Einzahl für die Zähler einmal Einzahl, einmal die Mehrzahl... verwirrend, aber kein Fehler
    i: ??? wozu??

    Bevor wir zu den Schleifen kommen: Wozu machst du zwei try-Blocks auf. Unnötig. Mach einfach zwei catch-Blöcke in den ersten try-Block

    Hier die Schleife, diesma als Kommentare im Code:

    // ok, aber verstehst du was in der Bedinung passiert und warum??
    while ((zeile = br.readLine()) != null) {
       // der zähler ist ja für array da. Ein Array beginnt aber bei 0 (!!)
       // daher erst die Verarbeitung, dann das hochzählen.
       zeilen++;
       // siehe kommentar bei der ersten Schleife. 
       // Das ist dieselbe Prüfung und führt daher zu einer Endlosechleife, da sich
       // zeile in der Schleife nicht verändert also niemals == null wird.
       // denk nochma darüber nach was deine Idee bei diesem Konstrukt war und
       // was eine bessere möglichkeit wäre die Schleifen durchläufe zu      
       // kontrollieren. 
       while(zeile !=null){
          // der restliche ansatz ist in Ordnung. 
          feld[zeilen][reihe]= zeile.charAt(reihe);
          reihe++;             
          System.out.println();
       }
    
       i++;
    }
    

    Ich hoffe ich konnte dir auf die Sprünge helfen...

    Huldigt dem König!



  • Okay vielen Dank.
    Eure Beiträge haben mir sehr geholfen und ich denke ich habe es jetzt auch geschafft.

    Meine Lösung sieht nun so aus:

    public int[][] open() {
    	    int feldopen[][] = new int[spielfeldGröße][spielfeldGröße];
    	    try {
    	    	      BufferedReader br = new BufferedReader(new FileReader("schreiben.txt"));
    	    	      String line = null;
    	    	      int spalte = 0;
    
    	    	      while ((line = br.readLine()) != null) {
    
    	    	    	  for(int reihe = 0; reihe != feldopen.length; reihe++){
    
        	    			  feldopen[spalte][reihe]= line.charAt(reihe) - 48;    
    
        	    		  }
    
        	    		  spalte++;
    
    	    	        }
    	    	      }catch (FileNotFoundException e1) { e1.printStackTrace();}
    	    			catch (IOException e) {e.printStackTrace(); }
    
    	    	return feldopen;
    	    }
    }
    


  • Können die Zellen zweistellige Werte einnehmen beinhalten?



  • Eigentlich nicht. Ich brauche nur die Werte von 0 - 5.

    Jedoch aus Interesse, wie könnte man es Lösen ohne einfach ein Zeichen weiter zu springen? Ich nehme an ich bräuchte ein Trennzeichen(Komma oder Leerzeichen zwischen den Werten)?

    MfG



  • Da gibt es zwei Wege:

    Rhombicosidodecahedron schrieb:

    Ich würde dein Format so abwandeln, sodass das in der ersten Zeile die Breite und in der zweiten die Höhe steht und danach erst deine Daten, sodass du zuerst die ersten beiden Zeilen einließt und davon das Array erstellst.

    Beim zweiten wäre es besser Scanner zu nehmen [...]

    [...] um die Zahlen mit nextInt auslesen zu lassen, dabei wird das dann automatisch umgewandelt. Zur nächsten Zeile springt man dann mit nextLine ohne dabei den Rückgabewert zu beachten. So hast du auch nicht dieses unschöne - 48 im Quelltext.



  • DrunkenMastered schrieb:

    [...] Ich nehme an ich bräuchte ein Trennzeichen(Komma oder Leerzeichen zwischen den Werten)?

    ... oder eine feste Stellenzahl > 1,
    ... oder einen Längenprefix vor dem Wert,
    ... oder gleich einen FileOutputStream und writeObject() ...


Anmelden zum Antworten