# Objekte in externer Datei schreiben



## MaxK1990 (5. Juli 2010)

Hey Leute, da bin ich nochmal mit ner neuen Frage.

Und zwar möchte ich gerne das gezeichnete auf der Leinwand in eine externe Datei speichern können, sodass ich das ganze zu einem späteren Zeitpunkt erneut aufrufen kann, oder an Freunde verschicken kann. Sie die Datei einlesen und das gleiche vor sich haben. Also sozusagen wie ein "Savegame" bei Spielen oder eine Word-Datei, die überall dann gleich aussieht.

Mit Datenbankanbindungen kenne ich mich eigentlich aus, sodass ich eine Datenbankanbindung auf MySQL oder Microsoft Access Datenbanken aufbauen, Sachen hinzufügen und auslesen kann.
Habe mir überlegt eine Microsoft Database zu verwenden, dann die Objekte in die Datenbank reinschreibe und sie per jdbcdbc Treiber wieder auslesen lasse. Aber es muss^doch eine andere Möglichkeit geben ein .sav oder ähnliches zu erstellen und nicht extra eine risieige Datenbank dranzuhängen.

Wie immer Danke im Voraus

Euer Max


----------



## sheel (5. Juli 2010)

Natürlich, schau dir mal die Klassen File, FileWriter, BufferedWriter, FileReader, BufferdReader etc an


----------



## Kai008 (5. Juli 2010)

Wenn ich dich richtig verstanden habe, willst du ein Bild von nen Programm abspeichern.
Prinzipiell kannst du mit Robot einen Screenshot machen.
Wenn du alle Elemente in ein Image zeichnest, kannst du auch per ImageIO ein Bild per File oder Stream schreiben.
Ansonst schau dir ObjectOutput/Input-Stream, Serializable und Persistente Objekte  an.


----------



## MaxK1990 (5. Juli 2010)

Nene,
ich will mehrere Objekte in eine Datei schreiben.
Ich hab ein kleines Malprogramm und ich will die gezeichneten Objekte abspeichern inner Datei, dass ich später den Zustand rekonstruieren kann.


----------



## CPoly (5. Juli 2010)

Da du nur von "Objekten" redest, würde ich dir einen ObjectOutputStream bzw. ObjectInputStream empfehlen. Jeweils zusammen mit FileWriter/FileReader.
Das setzt natürlich vorraus, dass du den gesamten Inhalt der Malfläche in einer geeigneten Datenstruktur gespeichert hast. Denn wenn das nicht so ist, hast du ja lediglich eine Bitmap, welche du dann speichern musst.


----------



## MaxK1990 (5. Juli 2010)

Also ich hab hier ne ArrayLIst mit verschiedenen Objekten gefüllt.
EInmal eben ein Rechteck, einmal ein Kreis (blabla), kann ich diese wie du meinst mit OBjextOutputWriter speichern?


----------



## Kai008 (5. Juli 2010)

Warum sagst du nicht einfach, das du eine Speicherfunktion brauchst?
Geh doch einfach alle Objekte durch, und speichere sie ab.
z. B.:


```
typ;parameter0;parameter1;parameter2
typ;parameter0;parameter1;parameter2
```


```
TYPE_RECTANGLE = 0;
TYPE_RECTANGLE = 1;
OVAL_RECTANGLE = 2;
---------------------------------
1;10;20;100;30
2;50;50;10;10
0;0;10;100;10
0;0;100;100;100
```

Und beim Laden wertest du den Typ aus, dementsprechend die Parameter und rekonstruierst die Objekte.


----------



## CPoly (5. Juli 2010)

MaxK1990 hat gesagt.:


> Also ich hab hier ne ArrayLIst mit verschiedenen Objekten gefüllt.
> EInmal eben ein Rechteck, einmal ein Kreis (blabla), kann ich diese wie du meinst mit OBjextOutputWriter speichern?



Ja siehe http://java.sun.com/j2se/1.4.2/docs/api/java/io/ObjectOutputStream.html



> An ObjectOutputStream writes primitive data types and graphs of Java objects to an OutputStream. The objects can be read (reconstituted) using an ObjectInputStream. Persistent storage of objects can be accomplished by using a file for the stream.





Kai008 hat gesagt.:


> Warum sagst du nicht einfach, das du eine Speicherfunktion brauchst?
> Geh doch einfach alle Objekte durch, und speichere sie ab.
> z. B.:
> 
> Und beim Laden wertest du den Typ aus, dementsprechend die Parameter und rekonstruierst die Objekte.



Eben dafür ist der ObjectStream gedacht.

Edit: Siehe auch mein Beispiel in diesem Thread(Erst ein paar Tage alt).
http://www.tutorials.de/forum/java/362179-farben-und-strings.html


----------



## MaxK1990 (5. Juli 2010)

Edit:// Hat sich erledigt


----------



## MaxK1990 (5. Juli 2010)

Hmm ich das ganze jetzt mal auf einen Button gelegt und folgendes auf die Taste gelegt (actionPerformed):

public void speichern(){
		try{
			FileOutputStream file = new FileOutputStream("C:/Users/Max/Desktop/test.erm");
			ObjectOutputStream oos = new ObjectOutputStream(file);

			oos.writeObject(formen);

			oos.close();
		}
		catch(Exception ex){
			JOptionPane.showMessageDialog(null, "Speichen fehlgeschlagen!");
			System.out.println(ex);
		}
	}



Da bekomme ich aber folgende Fehlermeldung zurück:

java.io.NotSerializableException: paketFachklassen.Attribut


Was bedeutet NOtSerializableException?


----------



## Kai008 (5. Juli 2010)

Sämtliche Klassen müssen das Interface Serializable implementieren.


----------



## Akeshihiro (5. Juli 2010)

Ich denke es geht um das Programm, das ich dir korrigiert hab. Wenn ja, dann musst du nix dolles machen, eigentlich nur in der Klasse Form etwas hinzufügen:

```
import java.io.Serializeable;

public class Form implements Serializeable {
// ...
}
```


----------



## MaxK1990 (5. Juli 2010)

Hab ich bereits
Die Speichern-Methode funktioniert jetzt auch nur beim Laden hab ich da noch ne Frage. Ich habe die Laden-Methode bereits so geschrieben:

public void laden(){
		try{
			FileInputStream file = new FileInputStream("C:Users/Max/Desktop/test.erm");
			ObjectInputStream ois = new ObjectInputStream(file);

			formen.add(ois.readObject());




		}
		catch(Exception ex){
			JOptionPane.showMessageDialog(null, "Laden fehlgeschlagen!");
			System.out.print(ex);
		}
	}

Da sagt er mir aber, dass das ganze nicht anwendbar ist, da er eine Form brauch und kein Objekt.
Mein anderes Problem ist, wenn ich jetzt jemandem die Datei schicke weiß er ja nicht wieviele Objekte hier gezeichnet werden sollen, bzw. wieviele in der Datei gespeichert sind. Wie arbeite ich alle Objekte ab ohne zu wissen wieviele es sind. Vllt. mit ner while-Schleife?


----------



## Akeshihiro (5. Juli 2010)

Beim lesen der Objekte wird ein Object zurückgegeben, das musst du dann eben noch entsprechend casten, ist aber keine dolle Sache. Und das mit der Anzahl der Objekte ist auch kein Ding. Wenn die Datei zuende ist, dann gibt readObject() null zurück, also einfach darauf prüfen und solange nicht null zurückgegeben wird, weiterarbeiten ^^

Hier mal der Code:

```
public void laden() {
	ObjectInputStream ois = null;
	try {
		ois = new ObjectInputStream(new FileInputStream(
				"C:/Users/Max/Desktop/test.erm"));
	} catch(FileNotFoundException e1) {
		e1.printStackTrace();
	} catch(IOException e1) {
		e1.printStackTrace();
	}
	if(ois == null) { return; }
	try {
		Object obj = null;
		while((obj = ois.readObject()) != null) {
			formen.add((Form)obj);
		}
		repaint();
	} catch(EOFException e) {
		// Datei am Ende
	} catch(Exception ex) {
		JOptionPane.showMessageDialog(null, "Laden fehlgeschlagen!");
		ex.printStackTrace();
	} finally {
		ois.close();
	}
}
```

Ich glaub mit dir werden wir noch ne längere Zeit zu tun haben ^^

EDIT: Hab mich mit der Rückgabe und null vertan, damit findet man nicht heraus, ob die Datei am Ende ist. Aber es wird eine EOFException geworfen, die kann man abfangen ^^ Code geändert ...


----------



## MaxK1990 (5. Juli 2010)

Hatte es bisher so:


```
public void laden(){
		try{
			FileInputStream file = new FileInputStream("C:/Users/Max/Desktop/test.erm");
			ObjectInputStream ois = new ObjectInputStream(file);
			
			
			formen.add((Form) ois.readObject());
			ois.close();
			
			this.repaint();
			
		}
		catch(Exception ex){
			JOptionPane.showMessageDialog(null, "Laden fehlgeschlagen!");
			System.out.print(ex);
		}
	}
```


Beim Auführen bringt er mir ne "Java heap space" Fehlermeldung java.util.OutOfMemoryError


----------



## MaxK1990 (5. Juli 2010)

Akeshihiro hat gesagt.:


> Ich glaub mit dir werden wir noch ne längere Zeit zu tun haben ^^




Und ist das denn so schlimm? Jeder hat mal unten angefangen


----------



## Akeshihiro (5. Juli 2010)

Nein, so war das nich gemeint xD So böse bin ich nun auch wieder nich -.-


----------



## SPiKEe (8. Juli 2010)

beduetet nichts anderes als das dein HEAP vollgelaufen ist
oder mal ausführlicher
wenn du java startest *egal ob es automatisch gestartet wird durch den browser weil er n applet laden soll oder direkt als applikation* erhält es ein stück vom RAM ...
wie viel java bekommt ist teilweise festgelegt ... werden keine zusätzlichen parameter übergeben wird es mit *und jetzt korrigiert mich bitte ich weis es nicht mehr genau* mit 40MB/42MB oder 64MB verwendbarem RAM gestartet *wie gesagt ich weis es jetzt nicht genau wie viel aber ich meine es war eine dieser drei zahlen*
das beutet das du maximal soviele daten gleichzeitig im RAM halten kannst ... und wenn du mehr laden willst wird diese exception geworfen *in der regel wird dann erstmal der GC ausgeführt und wenn auch das nichts hilft schießt sich java meist ab *ist zum. bei mir so mit GUI's die dann einfrieren weil kein RAM zur verarbeitung bereit steht*
nun kannst du aber java als parameter übergeben wie viel RAM beim start schon gleich reserviert werden soll und wie viel java maximal haben darf
das geschiet mit

```
java -Xms= -Xmx=
```
mit -Xms bestimmts du wie viel ram zum start reserviert wird ... mit -Xmx wie viel maximal beansprucht werden darf
*bei multi-threaded und stacked programmierung kann auch noch -Xss sinnvoll werden um die größe der stacks festzulegen*

grund für heap-overflow
du lädts zu viele / zu große objekte gleichzeitig in den RAM
du solltest vllt bei deinem programm so vorgehen das du nicht alle objekte in einem arrays hältst sondern vom gezeichneten einen screenshot machst und nur diesen speicherst
natürlich haben beide varianten ihre vor und nachteile ... aber ich denke für ein einfaches "malprogramm" sollte die variante mit dem screenshot die bessere sein
wenn du wirklich an deinem object-chaos festhalten willst musst du entweder die heap-größen erhöhen *was sich nicht wirklich elegant macht da sonst alle die es verwenden diesen schritt tun müssen* oder nach einer möglichkeit suchen deinen heap nicht ganz so vollzukrachen ...


----------



## Akeshihiro (8. Juli 2010)

Bin ich im falschen Film?


----------



## Kai008 (8. Juli 2010)

Warum fliegt keine CastException? Du serialisierst doch die List und castest es bei der Deserialisierung in einer Form.


----------



## Akeshihiro (8. Juli 2010)

Kai008 hat gesagt.:


> Warum fliegt keine CastException? Du serialisierst doch die List und castest es bei der Deserialisierung in einer Form.



Weil er nicht mehr die Liste serialisiert, sondern die einzelnen Objekte darin. Also keine Angst, das passt schon ^^


----------

