# Der BufferedReader mag mich nicht



## Messoras (30. Jun 2014)

Hallo,
Ich bin's wieder und immernoch mit dem gleichen Projekt...
Ich versuche momentan die Speicherstände meines Spiels aus einer Datei in einen String zu schreiben und den dann zu einer Klasse zu machen.
Mein Problem ist die größe der Datei... Sie hat ca. 1000 Zeilen und die sind randvoll.
Deshalb habe ich versucht sie alle nacheinander an den String anzuhängen, undzwar so:

```
FileReader fr = new FileReader(dateien[i]); //dateien[i] ist vorher definiert.
   BufferedReader br = new BufferedReader(fr);
   String info = "";
   String zeile = "";

   while((zeile = br.readLine()) != null) {
       info += zeile;
       System.out.println("Zeile angehängt");
   }
   System.out.println("Info gelesen");
   br.close();
```
Sollte ja eigentlich kein Problem sein, aber der BufferedReader macht nur 2 Zeilen.
Die Konsole zeigt mir an:

```
Zeile angehängt
Info gelesen
Fehler beim Lesen der Speicherstände
```
Der "Fehler beim Lesen der Speicherstände" kommt daher, dass die Nachfolgende Deklaration der Speicherstand Methode mit dem unvollständigen String arbeitet.
Eigentlich sollte der BufferedReader ja solange neue Zeilen lesen, bis keine mehr da sind, aber warum macht er das nur ein mal?


----------



## VfL_Freak (30. Jun 2014)

Moin,

sie auf den ersteb Blick ok aus ... aber:
was ist "dateien" ???:L
was steht denn in der Datei ???:L
Vielleicht nur eine Zeile ???:L 

BTW: ein Konstrukt in der Art

```
myString += anotherString
```
ist generell keine gute Idee, da hierbei jedesmal neue Stringinstanzen erzeugt werden!
Nimm' besser einen Stringbuilder!

```
StringBuilder myString = new StringBuilder;
...
myString.append( anotherString );
```

Gruß
Klaus


----------



## Messoras (30. Jun 2014)

> Sie hat ca. 1000 Zeilen und die sind randvoll


ca 1000 Zeilen, nicht nur eine...


----------



## taro (30. Jun 2014)

was gibt dir ein 

```
System.out.println(zeile)
```

vor

```
info += zeile;
```
aus?


----------



## Messoras (30. Jun 2014)

Das gibt mir die Zeile aus. Ganz normal. Aber am Ende stehen da wieder nur die beiden obersten Zeilen.


----------



## taro (30. Jun 2014)

> Aber am Ende stehen da wieder nur die beiden obersten Zeilen.



Ich schiebs einfach mal auf die Uhrzeit ... der Satz will mir nicht in den Kopf ... poste doch bitte einmal eine konkrete Ausgabe.


----------



## taro (30. Jun 2014)

Ich habs dann doch mal kurz getestet ... funktioniert wie es soll ...

woher kommt eigentlich


```
Fehler beim Lesen der Speicherstände
```
?

Hantierst du evtl. da noch mit irgendwas anderem?

Wo fängst du FileNotFoundException und IOException ab?


----------



## Messoras (1. Jul 2014)

Also... Einmal die gesamte Methode hier:

```
laden = true;
            machknopf("Zurück",getWidth()/2-30,140,60,20,"ladenstopp");
            int zaehler = 0;
            //Provisorisch
            //             speicherstaende.toFirst();
            //             while (speicherstaende.hasAccess()) {
            //                 Speicherstand bla = (Speicherstand) speicherstaende.getObject();
            //                 machknopf(bla.name,getWidth()/2-90,175+zaehler,180,20,"laden/"+bla.name);
            //                 zaehler += 35;
            //                 speicherstaende.next();
            //             }

            //Laden aus Datei
            File path = new File("main/saves");
            File[] dateien = path.listFiles();
            //Hier werden die Speicherstände auf 0 gesetzt!
            speicherstaende = new List();

            for (int i = 0; i < dateien.length; i++) {
                try {

                    FileReader fr = new FileReader(dateien[i]);
                    BufferedReader br = new BufferedReader(fr);
                    String info = "";
                    String zeile = "";

                    while((zeile = br.readLine()) != null) {
                        info += zeile;
                        System.out.println("Zeile angehängt:");
                        System.out.println(zeile);
                    }
                    System.out.println("Info gelesen");
                    br.close();
                    //Konstruktor:String n, Spielfeld m, List k,int x1, int y1
                    //toString: name+"#"+x+"#"+y+"#"+map.toString()+"#"+kis
                    //toString Zeug//
                    Speicherstand sps = new Speicherstand(info);
                    System.out.println("Speicherstand erstellt");
                    speicherstaende.append(sps);
                    System.out.println("Speicherstand an Liste angehängt");
                    machknopf(sps.name,getWidth()/2-90,175+zaehler,180,20,"laden/"+sps.name);
                    zaehler += 35;
                }

                catch(Exception e) {
                    System.out.println("Fehler beim Lesen der Speicherstände");
                }
            }
```
Sry was die Ausgabe angeht, aber:


> Der Text, den Sie eingegeben haben, besteht aus 529420 Zeichen und ist damit zu lang. Bitte kürzen Sie den Text auf die maximale Länge von 25000 Zeichen.



Jedenfalls wird nur die oberste Zeile der Datei eingelesen.

#EDIT:
Gibt es so eine Art Längenbegrenzung für Strings? Denn die wäre mit einer halben Millionen Zeichen denke ich überschritten, aber wenn das ein normales array aus chars ist ohne begrenzung dürfte der ja an die Grenze von int gehen, also.... ehm 2.147.483.647,
zumindest sollte er mehr als nur die erste Zeile erreichen.

Achja das Error Terminal gibt

```
Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space
```
aus, also liegt das an dem unvollendeten String.


----------



## Topfpflanze (1. Jul 2014)

Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space

bedeutet schlicht und einfach, dass Java keinen Speicher mehr hat.
Den Java verfügbaren Speicher kannst du einfach mittels eines Kommandozeilenparameters erhöhen.


----------



## Messoras (1. Jul 2014)

Oh Gott bin ich dämlich... Da erkenne ich das simple Wort memory aus 50cm Entfernung nicht... :lol:
Danke, dass du mich drauf hingewiesen hast.
Wie mache ich das denn mit dem Kommandozeilenparameter? muss ich da direkt mit einem char Array arbeiten und dann mit BufferedReader.read() einen anhängen? Wie bestimme ich die Größe für das Array?


----------



## Ananaskirsche (1. Jul 2014)

soweit ich weiss mit 

```
-xmx1G -xms1G
```
für 1GB Speicher


----------



## Messoras (1. Jul 2014)

Also ich habe es jetzt so probiert, aber ich bekomme immernoch ne OutOfMemory Exception:

```
laden = true;
            machknopf("Zurück",getWidth()/2-30,140,60,20,"ladenstopp");
            int zaehler = 0;
            //Provisorisch
            //             speicherstaende.toFirst();
            //             while (speicherstaende.hasAccess()) {
            //                 Speicherstand bla = (Speicherstand) speicherstaende.getObject();
            //                 machknopf(bla.name,getWidth()/2-90,175+zaehler,180,20,"laden/"+bla.name);
            //                 zaehler += 35;
            //                 speicherstaende.next();
            //             }

            //Laden aus Datei
            File path = new File("main/saves");
            File[] dateien = path.listFiles();
            //Hier werden die Speicherstände auf 0 gesetzt!
            speicherstaende = new List();

            for (int i = 0; i < dateien.length; i++) {
                try {

                    FileReader fr = new FileReader(dateien[i]);
                    BufferedReader br = new BufferedReader(fr);
                    java.lang.StringBuilder info = new StringBuilder();
                    String zeile = "";

                    while((zeile = br.readLine()) != null) {
                        info.append(zeile);
                        System.out.println("Zeile angehängt:");
                    }
                    System.out.println("Info gelesen");
                    br.close();
                    //Konstruktor:String n, Spielfeld m, List k,int x1, int y1
                    //toString: name+"#"+x+"#"+y+"#"+map.toString()+"#"+kis
                    //toString Zeug//
                    //String name0 = info.substring(15,info.indexOf("#"));
                    //System.out.println(name0);
                    //Speicherstand sps = new Speicherstand(name0,new Spielfeld("1",10,10,0),k0,x0,y0);
                    Speicherstand sps = new Speicherstand(info.toString());
                    System.out.println("Speicherstand erstellt");
                    speicherstaende.append(sps);
                    System.out.println("Speicherstand an Liste angehängt");
                    machknopf(sps.name,getWidth()/2-90,175+zaehler,180,20,"laden/"+sps.name);
                    zaehler += 35;
                }

                catch(Exception e) {
                    System.out.println("Fehler beim Lesen der Speicherstände");
                }
            }
```

Übrigens wieder schon nach der ersten Zeile.


----------



## Topfpflanze (1. Jul 2014)

Wie gross ist denn deine Datei?

In welcher ProgrammZeile tritt der Fehler auf?


----------



## Messoras (1. Jul 2014)

Die Datei ist riesig... Ca 1000 Zeilen, aber der Fehler tritt immer schon nach der ersten Zeile auf.
Das sehe ich an der Konsole, die ausgibt:

```
Zeile angehängt:
Info gelesen
```


----------



## Topfpflanze (1. Jul 2014)

Wiviele KiloByte hat deine Datei?

In welcher Programmzeile tritt der Fehler auf?

Er sagt dir doch outofmemory at line...


----------



## FINF_AW_Alex (1. Jul 2014)

Hallöchen

Also ich denke es liegt daran das der Heap-Speicher von Java genau wie der Stack irgendwo auch begrenzt ist und deshalb musst du den erhöhen, ich selber hatte das problem noch nie aber habe einen Link dazu gefunden. Ich hoffe es hilft !!

Grüße Alex !!

Java Heapspace vergrößern - Forum - CHIP Online


----------



## Messoras (1. Jul 2014)

Die Dateien haben 514-516 kb, das soll aber auch noch groeßer werden, wenn die Maps sich ausdehnen...
Der Fehler tritt zuerst beim Konstruktor für das dreizigste Feld des Spielfelds oder so auf, wenn er versucht einen substring bis zum nächsten "#" zu machen.

Sollte ich die substrings auch per StringBuilder machen?

^Deshalb dachte ich auch erst es läge nur am unkompletten String


----------



## Topfpflanze (1. Jul 2014)

Wenn der Fehler im Konstruktor Auftritt wäre der Quelltext der Klasse vermutlich hilfreich. Zumindest alle Felder & der Konstruktor & alles was vom Konstruktor aufgerufen wird.


----------



## Messoras (1. Jul 2014)

Konstruktor Speicherstand:

```
public Speicherstand(String info) {
        //laden aus toString
        name = info.substring(15,info.indexOf("#"));
        String info2 = info.substring(info.indexOf("#")+1);
        x = Integer.parseInt(info2.substring(0,info2.indexOf("#")));
        String info3 = info2.substring(info2.indexOf("#")+1);
        y = Integer.parseInt(info3.substring(0,info3.indexOf("#")));
        String info4 = info3.substring(info3.indexOf("#")+1);
        String mapinfo = info4.substring(info4.indexOf("{Spielfeld}")+11,info4.indexOf("{/Spielfeld}"));
        //System.out.println("Speicherstand erstellt. Ausstehend: Map, Bots");
        map = new Spielfeld(mapinfo);
        String botinfo = info4.substring(info4.indexOf("{Bot}"+5));
        ki = new List();
        boolean h = true;
        while (h) {
            if (botinfo.startsWith("{/Spielfeld}")) {
                h = false;
            }
            else {
                ki.append(new Bot(botinfo));
                botinfo = botinfo.substring(botinfo.indexOf("{/Bot}")+6);
            }
        }

    }
```

Konstruktor Map:

```
public Spielfeld(String info) {
        //System.out.println("Spielfeld wird generiert ...");
        name = info.substring(0,info.indexOf("#"));
        String info2 = info.substring(info.indexOf("#")+1);
        breite = Integer.parseInt(info2.substring(0,info2.indexOf("#")));
        String info3 = info2.substring(info2.indexOf("#")+1);
        hoehe = Integer.parseInt(info3.substring(0,info3.indexOf("#")));
        String info4 = info3.substring(info3.indexOf("#")+1);
        feld = new Feld[breite][hoehe];
        String[][] feldinfo = new String[breite][hoehe];
        //System.out.println("Spielfeld erstellt. Generiert Boden");
        for (int i = 0; i < breite; i++) {
            for (int j = 0; j < hoehe; j++) {
                if (j > 0) {
                    feldinfo[i][j] = feldinfo[i][j-1].substring(feldinfo[i][j-1].indexOf("{/Feld}")+7);
                }
                
                else if (i > 0) {
                    feldinfo[i][j] = feldinfo[i-1][j].substring(feldinfo[i-1][j].indexOf("{/Feld}")+7); 
                }
                else {
                    feldinfo[i][j] = info4;
                }
                //System.out.println("Generiert Feld ["+i+"]["+j+"] ...");
                feld[i][j] = new Feld(feldinfo[i][j]);
                //System.out.println("Feld ["+i+"]["+j+"] generiert");
            }
        }
        //System.out.println("Boden generiert");
    }
```

Konstruktor Feld:

```
public Feld(String info) {
        //System.out.println("Feld wird generiert ...");
        name = info.substring(info.indexOf("{Feld}"+6,info.indexOf("#")));
        String info2 = info.substring(info.indexOf("#")+1);
        String isvoll = info2.substring(0,info2.indexOf("#"));
        voll = false;
        if (isvoll.equals("true")) {
            voll = true;
        }
        String info3 = info2.substring(info2.indexOf("#")+1);
        farbe = farbeaustext(info3);
        String flaecheninfo = info3.substring(info3.indexOf("#")+1);
        //System.out.println("Feld generiert. Ausstehend: Flaeche");
        flaeche = new Flaeche(flaecheninfo);
    }
```

Konstruktor Flaeche:

```
public Flaeche (String info) {
        //System.out.println("Flaeche wird generiert ...");
        name = info.substring(9,info.indexOf("#"));
        //System.out.println("Flaeche - Namen geladen");
        String info2 = info.substring(info.indexOf("#")+1);
        xPos = Integer.parseInt(info2.substring(0,info2.indexOf("#")));
        //System.out.println("Flaeche - X geladen");
        String info3 = info2.substring(info2.indexOf("#")+1);
        yPos = Integer.parseInt(info3.substring(0,info3.indexOf("#")));
        //System.out.println("Flaeche - Y geladen");
        String info4 = info3.substring(info3.indexOf("#")+1);
        breite = Integer.parseInt(info4.substring(0,info4.indexOf("#")));
        //System.out.println("Flaeche - Breite geladen");
        String info5 = info4.substring(info4.indexOf("#")+1);
        hoehe = Integer.parseInt(info5.substring(0,info5.indexOf("{/Flaeche}")));
        //System.out.println("Flaeche - Hoehe geladen");
        //System.out.println("Flaeche generiert.");
    }
```

Konstruktor Bot:

```
public Bot (String info) {
        name = info.substring(info.indexOf("{Bot}")+5,info.indexOf("#"));
        String info2 = info.substring(info.indexOf("#")+1);
        callback = info2.substring(0,info2.indexOf("#"));
        String info3 = info2.substring(info2.indexOf("#")+1);
        warten = Integer.parseInt(info3.substring(0,info3.indexOf("#")-1));
        String feldinfo = info3.substring(info3.indexOf("#")+1);
        feld = new Feld(feldinfo);
    }
```

Die Variablen, die gesetzt werden spielen denke ich keine große Rolle, deswegen habe ich die jetzt nicht großartig erleutert.


----------



## Topfpflanze (1. Jul 2014)

HAst du dir mal das Array feldInfo angeschaut? 
Ich glaube, dass feldinfo[0][0] die Info für ALLE Felder enthält,
feldinfo[1][0] die info für (ALLE-1) Felder enthält...

Da dürfte dein ganzer Speicher hin verschwinden


----------



## Messoras (1. Jul 2014)

Ja am Anfang ist der ziemlich lang, aber mit jedem Feld wird er kleiner...
Wie kann ich's besser machen?


----------



## Topfpflanze (1. Jul 2014)

Du könntest zum beispiel nur in einem Array nur die startindexe speichern, anstatt der gesamten strings, und von denen aus suchen (indexOf kann auch erst ab einem bestimmten Zeichen suchen)

Alternativ kannst du den ganzen String in die einzelnen Felddefinitionen zerlegen (Schau dir String.split an)

Alternativ, womit du auf so ziemlich alles verzichten kannst: XStream - Two Minute Tutorial
Dann hast du nurnoch deine Objekte, ohne die ganze String-Verarbeitung, und xstream liest und schreibt deine objekte. Allerdings dann in XML.


----------



## Messoras (1. Jul 2014)

Das mit den Startindexen verstehe ich nicht so ganz, aber diese xStream Geschichte sieht praktisch aus. Ich versuche mal mir das zu installieren.

Geht das mit splitString so: 
	
	
	
	





```
String[] felderinfo = info4.split("{/Feld}{Feld}"+7);
```
 ?

->

```
public Spielfeld(String info) {
        //System.out.println("Spielfeld wird generiert ...");
        name = info.substring(0,info.indexOf("#"));
        String info2 = info.substring(info.indexOf("#")+1);
        breite = Integer.parseInt(info2.substring(0,info2.indexOf("#")));
        String info3 = info2.substring(info2.indexOf("#")+1);
        hoehe = Integer.parseInt(info3.substring(0,info3.indexOf("#")));
        String info4 = info3.substring(info3.indexOf("#")+1);
        feld = new Feld[breite][hoehe];
        //String[][] feldinfo = new String[breite][hoehe];
        //System.out.println("Spielfeld erstellt. Generiert Boden");
        String[] felderinfo = info4.split("{/Feld}{Feld}"+7);
        int zaehler = 0;
        for (int i = 0; i < breite; i++) {
            for (int j = 0; j < hoehe; j++) {
                feld[i][j] = new Feld(felderinfo[zaehler]);
                zaehler++;
                //System.out.println("Feld ["+i+"]["+j+"] generiert");
            }
        }
        //System.out.println("Boden generiert");
    }
```

So kriege ich zwar keine OutOfMemory Meldung, aber immernoch "Fehler beim Lesen der Speicherstände"


----------



## Harry Kane (1. Jul 2014)

Müssen deine Spielstand-Dateien normale, mit einem Texteditor lesbare Dateien sein?
Wenn nein, würde ich mir mal DataOutput/InputStream anschauen.


----------



## Messoras (1. Jul 2014)

Müssten sie eigentlich nicht und ich hatte auch erst gedacht, dass ich das am besten mit so einer ini Datei oder so hinkriege, dann habe ich es aber doch mit Textdateien gemacht, weil mir das irgendwie leichter fällt, auch wenn es länger dauert.


----------



## Messoras (1. Jul 2014)

Das Programm bleibt bei mir genau bei

```
String[] felderinfo = info4.split("{/Feld}{Feld}"+7);
```
hängen, allerdings sagt das Errorterminal nichts, ich sehe nur meine Fehlermeldung "Fehler beim Lesen der Speicherstände"


----------



## Harry Kane (1. Jul 2014)

Messoras hat gesagt.:


> Das Programm bleibt bei mir genau bei
> 
> ```
> String[] felderinfo = info4.split("{/Feld}{Feld}"+7);
> ...


Das ist doch genau das, was du in deinem Codeschnipsel aus Post #12 programmiert hast? :bahnhof:
Wenn du eine aussagefähige Fehlermeldung möchtest, dann lass dir doch einfach den stack trace ausgeben.


----------



## Topfpflanze (1. Jul 2014)

```
catch(Exception e) {
    System.out.println("Fehler beim Lesen der Speicherstände");
}
```

Füg da mal ein e.printStackTrace() ein.
Dann siehst du auch den Fehler.


----------



## Messoras (2. Jul 2014)

Also der StackTrace gibt folgendes aus:

```
java.util.regex.PatternSyntaxException: Illegal repetition
{/Feld}{Feld}7
```
and der Stelle, wo steht 
	
	
	
	





```
String[] felderinfo = info4.split("{/Feld}{Feld}"+7);
```


----------



## Topfpflanze (2. Jul 2014)

Als erstes, die +7 ist überflüssig.
Als zweites das was du der funktion gibst ist ein sogenannter Regulärer Ausdruck (Regex), probiere mal 

```
info4.split(Pattern.quote("{/Feld}{Feld}"));
```


----------



## Messoras (2. Jul 2014)

Cannot find symbol - variable Pattern

Btw. Die +7 ist nicht unwichtig, weil ich das ja zwischen {/Feld} und {Feld} splitten will und nicht vor {/Feld}.


----------



## turtle (2. Jul 2014)

> catch(Exception e) {
> System.out.println("Fehler beim Lesen der Speicherstände");
> }


So etwas ist extrem SCHLECHTER Programmierstil!

Warum?


Du catched  ALLE Exceptions, obwohl ich derzeit "nur" sehe, das dein Code FileNotFoundException 	und IOException werfen könnte. Also solltest du auch nur diese catchen.
Du unterdrückst hilfreiche Informationen. Beispielsweise wäre es bei einer FileNotFoundException  doch ganz interessant, um welche Datei es sich handelt. Du aber machst  nur System.out.println("Fehler beim Lesen der Speicherstände");
Zum Exception-Handling gehört, nun ja, das du die Exception behandelst. Und das blosse Ausgeben ist KEINE Behandlung. Wenn du da nichts Gescheites machen kannst, ist es besser, diese zu werfen,nicht zu catchen und den Aufrufer sich darum kümmern zu lassen.

Aktuell solltest du auf jeden Fall ALLE Informationen ausgeben, so das du und wir nicht raten müssen.


```
} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
```


----------



## turtle (2. Jul 2014)

Sehe, das wohl ein Problem mit regulären Ausdruck vorliegt. 

```
String[] felderinfo = info4.split("{/Feld}{Feld}"+7);
```
Da benötigen wir (natürlich) den Inhalt von info4 und deine Erwartung, wie der Split aussehen soll?


----------



## Messoras (2. Jul 2014)

info4 ist ein sehr langer String, der alle Felder, mit deren toString Methode hintereinander hängt.
Die sieht ca so aus:

```
{Feld}2:40#false#java.awt.Color[r=50,g=200,b=20]#{Flaeche}feldflaeche2:40#20#400#10#10{/Flaeche}{/Feld}
```

Der ganze info4 String also dann so:

```
{Feld}Spielerspawn#false#java.awt.Color[r=255,g=255,b=255]#{Flaeche}spawnflaeche#0#0#10#10{/Flaeche}{/Feld}{Feld}0:1#false#java.awt.Color[r=50,g=200,b=20]#{Flaeche}feldflaeche0:1#0#10#10#10{/Flaeche}{/Feld}{Feld}0:2#false#java.awt.Color[r=50,g=200,b=20]#{Flaeche}feldflaeche0:2#0#20#10#10{/Flaeche}{/Feld}{Feld}0:3#false#java.awt.Color[r=50,g=200,b=20]#{Flaeche}feldflaeche0:3#0#30#10#10{/Flaeche}{/Feld}{Feld}0:4#false#java.awt.Color[r=50,g=200,b=20]#{Flaeche}feldflaeche0:4#0#40#10#10{/Flaeche}{/Feld}{Feld}0:5#false#java.awt.Color[r=50,g=200,b=20]#{Flaeche}feldflaeche0:5#0#50#10#10{/Flaeche}{/Feld}{Feld}0:6#false#java.awt.Color[r=50,g=200,b=20]#{Flaeche}feldflaeche0:6#0#60#10#10{/Flaeche}{/Feld}
...
```

der Split sollte also ca. so sein:

```
feldinfo[0] = "{Feld}Spielerspawn#false#java.awt.Color[r=255,g=255,b=255]#{Flaeche}spawnflaeche#0#0#10#10{/Flaeche}{/Feld}"
feldinfo[1] = "{Feld}0:1#false#java.awt.Color[r=50,g=200,b=20]#{Flaeche}feldflaeche0:1#0#10#10#10{/Flaeche}{/Feld}"
feldinfo[2] = "{Feld}0:2#false#java.awt.Color[r=50,g=200,b=20]#{Flaeche}feldflaeche0:2#0#20#10#10{/Flaeche}{/Feld}"
```
...


----------



## Harry Kane (2. Jul 2014)

Messoras hat gesagt.:


> Cannot find symbol - variable Pattern
> {/Feld}.


Gemeint ist java.util.regex.Pattern. Da fehlt wohl ein import-statement.
Alternativ kannst du auch die geschweiften Klammern, die in regulären Ausdrücken eine spezielle Bedeutung haben, escapen:

```
info4.split("\\{/Feld\\}\\{Feld\\}");
```
Und was soll da nochmal genau die 7? Das splitten liefert dir lediglich ein array von Strings. Ich sehe nicht wozu man da eine Positionsangabe bräuchte. Wenn du weisst, dass nach dem Splitten einige der Einträge im String array noch führende oder anhängende Zeichen haben, die du nicht brauchst, musst du diese separat entfernen. Oder du entfernst sie aus dem Startstring vor dem splitten. In jedem Fall NICHT im demselben Schritt wie das eigentliche Splitten!
Die Fehlermeldung zeigt ja an, dass Java versucht hat, die Zeichenkette "{/Feld}{Feld}7" zum splitten zu verwenden, was ganz sicher nicht das ist, was du beabsichtigt hattest.


----------



## taro (3. Jul 2014)

Das sieht mir wie "verkapptes" XML aus ... warum nutzt du zur Speicherung nicht ganz simpel eine XML-Struktur?


----------



## Messoras (3. Jul 2014)

Wenn ich wüsste, wie das geht... 
Bin im zweiten Jahr Informatik an der Schule.
Aber ich lese mich da mal ein.


----------



## Topfpflanze (4. Jul 2014)

Probier mal XStream, da musst du dir um die Ein/Ausgabe keine wirklichen Gedanken mehr machen.


----------



## Messoras (4. Jul 2014)

Also ich habe jetzt versucht das mit einem FileOutputStream zu machen, aber da bekomme ich die Fehlermeldung:

```
java.io.NotSerializableException: Speicherstand
```
(Schon beim Speichern)

Der Speichercode:

```
knoepfe.toFirst();
            while (knoepfe.hasAccess()) {
                Flaeche co = (Flaeche) knoepfe.getObject();
                if (co.callback.equals("speichernan")) {
                    if (co.name.startsWith(speichertext)) {
                        co.name = speichertext;

                        speichern = false;
                        if (speichertext.length()>0) {
                            if (anzeige.equals("spiel")) {
                                Speicherstand speicherstand0 = new Speicherstand(speichertext,aktuell,bots,aktuell.spawnX,aktuell.spawnY);
                                //speicherstaende.append(speicherstand0);
                                Knopfcallback("speichernstopp");
                                text = "Karte "+speichertext+" gespeichert.";
                                textzeit = 100;
                                try {
                                    FileOutputStream fos = new FileOutputStream(path+speichertext+".msav");
                                    ObjectOutputStream oos = new ObjectOutputStream(fos);
                                    oos.writeObject(speicherstand0);
                                    fos.close();
                                    oos.close();
                                } catch (IOException e) {
                                    e.printStackTrace();
                                    System.out.println("Fehler beim Speichern in Datei.");
                                }
                                speichertext = "";
                            }
                            else if (anzeige.equals("editor")) {
                                Speicherstand speicherstand0 = new Speicherstand(speichertext,edited,edibots,edited.spawnX,edited.spawnY);
                                //speicherstaende.append(speicherstand0);
                                Knopfcallback("speichernstopp");
                                text = "Karte "+speichertext+" gespeichert.";
                                textzeit = 100;
                                try {
                                    FileOutputStream fos = new FileOutputStream(path+speichertext+".msav");
                                    ObjectOutputStream oos = new ObjectOutputStream(fos);
                                    oos.writeObject(speicherstand0);
                                    fos.close();
                                    oos.close();
                                } catch (IOException e) {
                                    e.printStackTrace();
                                    System.out.println("Fehler beim Speichern in Datei.");
                                }
                                speichertext = "";
                            }
                        }
                        else {
                            text = "Ungültiger Name.";
                            textzeit = 100;
                        }
                    }
                }
                knoepfe.next();
            }
```

Der Ladecode:

```
laden = true;
            machknopf("Zurück",getWidth()/2-30,140,60,20,"ladenstopp");
            int zaehler = 0;

            //Laden aus Datei
            File path = new File("main/saves");
            File[] dateien = path.listFiles();
            //Hier werden die Speicherstände auf 0 gesetzt!
            speicherstaende = new List();

            for (int i = 0; i < dateien.length; i++) {
                try {
                    FileInputStream fis = new FileInputStream(dateien[i]);
                    ObjectInputStream ois = new ObjectInputStream(fis);
                    Object obj = ois.readObject();
                    speicherstaende.append((Speicherstand)obj);
                }
                catch (IOException e) {
                    e.printStackTrace();
                }
                catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
            }
```

#EDIT: Jetzt habe ich bei Speicherstand einfach ein implements Serializable angehängt, aber dann bekomme ich

```
java.io.NotSerializableException: List
```
und von der List habe ich den Code nicht...


----------



## turtle (4. Jul 2014)

Das ist doch eine eindeutige Fehlermeldung, oder?
Sie sagt, das deine Klasse Speicherstand NICHT serialisiert werden kann.

Du solltest mal ein kleines Programm schreiben, das versucht einen Speicherstand zu serialisieren. 

Das liegt zu 99,99% daran, das Attribute in deiner Klasse drin sind, die nicht serialisiert werden können. 
So kannst du an deiner Klasse rumschrauben, bis die Serialisierung funktioniert.

Und klar kannst du eine List NICHT serialisieren, denn List ist ein Interface. 

Ob du eine Implementierung (ArrayList?) serialisieren kannst, ist natürlich auch davon abhängig, welche Objekte in der List stecken.

PS: Und natürlich hast du den Quellcode von List, weil der in src.zip des JDK steht


----------



## Messoras (4. Jul 2014)

Also da wäre einmal die Liste, weil ich da keinen Code von habe... Kann ich das nicht irgendwie umgehen?
Und 2. die Klasse Feld. Die gibt zwar keine Fehler beim übersetzen aus, aber sagt nurnoch "Compiling..."
und nichtmehr "Class compiled. No syntax errors":

```
import java.awt.*;
public class Feld implements java.io.Serializable
{
    public Flaeche flaeche;
    private boolean voll;
    public String name;
    private Color farbe;
    public Feld(String info) {
        System.out.println("Feld wird generiert ...");
        name = info.substring(info.indexOf("{Feld}"+6,info.indexOf("#")));
        System.out.println("Namen festgelegt.");
        String info2 = info.substring(info.indexOf("#")+1);
        String isvoll = info2.substring(0,info2.indexOf("#"));
        voll = false;
        if (isvoll.equals("true")) {
            voll = true;
        }
        String info3 = info2.substring(info2.indexOf("#")+1);
        farbe = farbeaustext(info3);
        String flaecheninfo = info3.substring(info3.indexOf("#")+1);
        System.out.println("Feld generiert. Ausstehend: Flaeche");
        flaeche = new Flaeche(flaecheninfo);
    }

    public Color farbeaustext(String s) {
        //java.awt.Color[r=50,g=200,b=20]
        int r = Integer.parseInt(s.substring(s.indexOf("r=")+2,s.indexOf("g=")-1));
        int g = Integer.parseInt(s.substring(s.indexOf("g=")+2,s.indexOf("b=")-1));
        int b = Integer.parseInt(s.substring(s.indexOf("b=")+2,s.indexOf("]")));
        return (new Color(r,g,b));
    }

    public Feld(String n, Flaeche f, boolean v) {
        name = n;
        flaeche = f;
        voll = v;
        farbe = Color.white;
    }

    public Feld(String n, Flaeche f, boolean v, Color frb) {
        name = n;
        flaeche = f;
        voll = v;
        farbe = frb;
    }

    public boolean isVoll() {
        return voll;
    }

    public boolean drinnen(int x0,int y0) {
        return (passt(x0,y0,flaeche));
    }
    
    public boolean passt(int x1, int y1, Flaeche f) {
        boolean h = false;
        if (x1 > f.getX() && x1 < f.getX() + f.getBreite() && y1 > f.getY() && y1 < f.getY() + f.getHoehe()) {
            h = true;
        }
        return h;
    }

    public String toString() {
        String isvoll = "false";
        if (voll) {isvoll = "true";}
        return ("{Feld}"+name+"#"+isvoll+"#"+farbe+"#"+flaeche.toString()+"{/Feld}");
    }
}
```

Inzwischen compiled aber nurnoch die Klasse Flaeche richtig...
Jetzt, nachdem ich das Projekt gespeichert habe, geht's wieder... buggt ein bisschen rum, aber List ist immernoch nicht serializable


----------



## turtle (4. Jul 2014)

Arbeitest du mit java.awt.List oder mit java.util.List?

Ersteres würde ich nicht verwenden.


----------



## Messoras (4. Jul 2014)

Ich benutze die Liste aus den Abiturvorgaben für 2015 (NRW), weil ich es mit der gelernt habe und mit der am besten klar komme...


----------



## turtle (4. Jul 2014)

Ich verstehe nicht was du machst???:L
Ich habe einen kleinen Test geschrieben, der eine List serialisiert und wieder de-serialisiert. Funzt bei mir problemlos.

```
@Test
    public void test() throws IOException, ClassNotFoundException {
	List list = new List();
	list.add("turtle");
	list.add("Messoras");
	FileOutputStream fos = new FileOutputStream("turtle.ser");
	ObjectOutputStream oos = new ObjectOutputStream(fos);
	oos.writeObject(list);
	fos.close();
	oos.close();

	FileInputStream fin = new FileInputStream("turtle.ser");
	ObjectInputStream ios = new ObjectInputStream(fin);
	List readList = (List) ios.readObject();
	assertEquals(2, readList.getItemCount());
	String[] items = list.getItems();
	assertEquals("turtle", items[0]);
	assertEquals("Messoras", items[1]);
    }
}
```


----------



## Messoras (4. Jul 2014)

Welche List benutzt du denn?


----------



## turtle (4. Jul 2014)

Normalerweise java.util.List

Der jUnit-Test aber mit java.awt.List


----------



## Messoras (4. Jul 2014)

Wie heisst da die toFirst Methode?
Bzw wie heisst die Methode, die den Index ausgibt?
toFirst wäre ja select(0), oder?


----------



## Messoras (4. Jul 2014)

ES FUNKTIONIERT!!! 
Ich habe mir den Code von meiner Liste im Internet besorgt und umgeschrieben, jetzt klappt es endlich.
Vielen Dank für eure Hilfe und Motivation!


----------

