Gecastete Objekte laden

klanawagna

Erfahrenes Mitglied
Hi Leute!

Ich habe eine Datei, in der ein Objekt gespeichert ist, welches auf (Object) gecastet ist. Meine Frage: wie kann ich das wieder zurück laden, so dass die Daten brauchbar sind,
und nächste Frage: wie mache ich das mit einem Array, welches per Append=true in eine Datei geschrieben wurde?

Bitte um Hilfe!


lg
klanawagna
 
Guten Abend.

So ganz verstehe ich die Frage nicht - willst du einfach nur ein Array von Objekten in ein File schmeißen und dann wieder rauslesen, und bekommst den von Object zu DeineKlasse[] nicht hin?

Dann hilft dir vielleicht dieser Code:

Java:
package de.tutorials.rocme;

import java.awt.Desktop;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

import org.omg.CORBA.Environment;

import sun.java2d.pipe.OutlineTextRenderer;

public class StupidThing implements Serializable {

	private String name;

	public StupidThing(String name) {
		super();
		this.name = name;
	}

	public static void main(String[] args) throws FileNotFoundException,
			IOException, ClassNotFoundException {
		// array anlegen
		StupidThing[] things = new StupidThing[3];
		// ein paar Things reinstecken
		for (int i = 0; i < 3; i++) {
			things[i] = new StupidThing("Stupid Thing " + i);
		}
		
		//Datei im "Home" Verzeichnis zum Speichern
		File f = new File(System.getProperty("user.home") + File.separatorChar + "tmpObjectFile");
		//rausschreiben
		ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(f, true));
		oos.writeObject(things);
		oos.close();
		//wiederholen
		ObjectInputStream ois = new ObjectInputStream(new FileInputStream(f));
		//toller Cast
		StupidThing[] newList =  (StupidThing[]) ois.readObject();
		//ausgeben
		for (StupidThing s : newList) {
			System.out.println("found " + s.name);
		}
		//und fertig
		ois.close();
	}
}

Gruß,

RoCMe
 
Hab ich versucht, es geht nicht!

Code:
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [LBestellvorgang.Bestellposition;
   at Testklassen.Main.main(Main.java:33)

Hab den Code:
Code:
static public void save(Object obj, String name)
	{
		OutputStream fos = null; 
		
		try 
		{ 
		  fos = new FileOutputStream(name); 
		  ObjectOutputStream o = new ObjectOutputStream( fos ); 
		  o.writeObject(obj);
		} 
		catch ( IOException e ) { System.err.println( e ); } 
		finally { try { fos.close(); } catch ( Exception e ) { } 
		}
	}

und laden tu ich über:

Code:
static public Object load(String name)
	{
		InputStream fis = null; 
		Object obj = new Object();
		try 
		{ 
		  fis = new FileInputStream( name ); 
		  ObjectInputStream o = new ObjectInputStream( fis ); 
		  obj = (Object) o.readObject(); 
		  
		  
		} 
		catch ( IOException e ) { System.err.println( e ); } 
		catch ( ClassNotFoundException e ) { System.err.println( e ); } 
		finally { try { fis.close(); } catch ( Exception e ) { } }
		return obj;
		
		
	}

der Aufruf:
Code:
adresse = (Adresse) Sichern.load("/tmp/Adresse.dat");
 
Moin,

Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [LBestellvorgang.Bestellposition;
at Testklassen.Main.main(Main.java:33)

Du solltest schon DIESE Stelle aus Deiner Main.java posten, damit man sieht, was DORT geschieht ..... :rolleyes:

Gruß
Klaus
 
Bei dem Code wird die Exception geworfen

Code:
		Bestellposition[] bpn = new Bestellposition[2];
		bpn = (Bestellposition[]) Sichern.load("/tmp/Bestellpositionen.dat", 3);

und bei dem Weiß ich nicht was kommt, weil eben die Exception for der Ausgabe kommt ;)
Code:
		Adresse adresse = new Adresse();
		adresse = (Adresse) Sichern.load("/tmp/Adresse.dat");
 
Bestellposition[] bpn = new Bestellposition[2];
bpn = (Bestellposition[]) Sichern.load("/tmp/Bestellpositionen.dat", 3);

Hallo,
was bedeutet denn die '3' :confused:

Zudem liefert Dir Deine Funktion 'load' etwas von Typ 'object' zurück! Dies kannst Du natürlich nicht auf ein Array casten ("Bestellposition[]"), allenfalls nacheinander auf "Bestellposition[0]" und "Bestellposition[1]" ...

Gruß
Klaus
 
Hallo,
Zudem liefert Dir Deine Funktion 'load' etwas von Typ 'object' zurück! Dies kannst Du natürlich nicht auf ein Array casten ("Bestellposition[]"), allenfalls nacheinander auf "Bestellposition[0]" und "Bestellposition[1]" ...
Klaus

Hm - warum denn nicht? Die ObjectInputStream.Methode readObject() liefert irgendein Objekt zurück, dass augelesen wurde. Warum sollte ich das nicht in ein Array casten können? Ein Array ist doch eigentlich auch nur ein spezielles Objekt?
Vorraussetzung ist natürlich immer, dass das gelesene Objekt auch wirklich ein Array des entsprechenden Typs ist - und nicht versehentlich eine Adresse oder sonstwas in die Datei geschrieben wurde...

Läuft denn das Adresse auslesen normal durch (Versuch mal ein try / catch um den Bestellvorgang- Teil, oder kommentiere ihn aus).

Gruß,

RoCMe

EDIT:

Java:
static public Object load(String name)
	{
		InputStream fis = null; 
		Object obj = new Object();
                ...
Du erstellt hier nunächst ein neues Objekt und versuchst dann, es mit dem aus der Datei geladenen Objekt zu überschreiben. Ersetze mal das "new Object()" durch ein null - dann wird null zurückgegeben, wenn das Laden schief geht. Das entspricht wohl eher dem "Standard". Bekommst du dann eine andere Fehlermeldung? Versuch mal, vor dem Cast zu prüfen, ob das erhaltene Object null ist...

Gruß,

RoCMe
 
Zuletzt bearbeitet:
Code:
static public Object[] load(String name, int capacity)
	{
		InputStream fis = null; 
		Object[] obj = new Object[capacity];
		int i;
		
		for(i=0; i<capacity; i++)
		{
			try 
			{ 
			  fis = new FileInputStream( name ); 
			  ObjectInputStream o = new ObjectInputStream( fis ); 
			  obj[i] = (Object) o.readObject(); 
			  
			  
			} 
			catch ( IOException e ) { System.err.println( e ); } 
			catch ( ClassNotFoundException e ) { System.err.println( e ); } 
			finally { try { fis.close(); } catch ( Exception e ) { } }
		}
		return obj;
		
		
	}

Das ist die Funktion für das Array (Sichern.load ist überladen)
Das mit dem einzelnen Objekt funktioniert!
 
Hallo!

Ich fürchte, du bringst da gerade einiges durcheinander!

Zuerst mal macht das IMHO überhaupt keinen Sinn, etwas nach Object zu casten. Alles in Java ist ein Object. Von der kleinsten bis zur größten Klasse sind haben sie ALLE von Object geerbt.

Wenn du in deinem ObjectInputStream die Methode readObject() aufrufst, dann bekommst du bereits ein Object zurück. Wie dieses Object genau aussieht, ist Java völlig egal - es ist in irgendeiner Weise ein "Ding", und damit gibt sich Java zufrieden.

Aber in den meisten Fällen willst du mit deinen Daten ja mehr anfangen, als Objects im Allgemeinen können. Also musst du Java erklären, dass es das betrachtete Object nicht mehr als Object, sondern als etwas anderes betrachten muss. Und das tust du, indem du castest:
Java:
Object myObject  = myObjectInputStream.readObject();
Adress myAdess = (Adress) myObject;
Hier liest du zunächst das Object aus dem InputStream. Und im 2. Schritt formst du dann aus dem erhaltenen Object eine Adresse.

Auf genau die gleiche Weise kannst du, statt einer Adresse, auch ein Array von Rechnungen erhalten, vorrausgesetzt natürlich, du hast vorher auch ein solches hineingeschoben!

Also noch mal in deinem Code:

Java:
//deine Load-Methode
static public Object load(String name)
	{
		InputStream fis = null; 
		Object obj = new Object();
		try 
		{ 
		  fis = new FileInputStream( name ); 
		  ObjectInputStream o = new ObjectInputStream( fis ); 
		  obj = (Object) o.readObject(); 
		  
		  
		} 
		catch ( IOException e ) { System.err.println( e ); } 
		catch ( ClassNotFoundException e ) { System.err.println( e ); } 
		finally { try { fis.close(); } catch ( Exception e ) { } }
		return obj;
		
		
	}

//deine Save-Methode
static public void save(Object obj, String name)
	{
		OutputStream fos = null; 
		
		try 
		{ 
		  fos = new FileOutputStream(name); 
		  ObjectOutputStream o = new ObjectOutputStream( fos ); 
		  o.writeObject(obj);
		} 
		catch ( IOException e ) { System.err.println( e ); } 
		finally { try { fos.close(); } catch ( Exception e ) { } 
		}
	}

//Methode zum Schreiben eines Arrays von BestellPositionen
public void writeBestellPos(BestellPos[] positions, fileName) {
  //Die Positionen mit obiger Funktion einfach in Datei fileName speichern
  save(positions, fileName)
}

//Methode zum Lesen eines Array von BestellPositionen

public BestellPos[] readBestellPos(String fileName) {
  //betreffende Datei auslesen lassen
  Object dateiInhalt = load(fileName);
  //aus Inhalt ein BestellPos "basteln"
  BestellPos[] result = (BestellPos[]) dateiInhalt;
  //zurückgeben
  return result;
}

Du steckst einfach das gesamte [] in einem Rutsch in die save-Methode, die du schon geschrieben hast. Die nimmt schließlich ein Object entgegen, und Java ist egal, ob dieses Object nun ein Auto, ein Pferd, eine Adresse oder sonstwas darstellt - es ist ein Object, und damit genug.
Intern wird ein wenig mehr gefordert - damit du das Object in den Stream stecken kannst, muss es das Interface Serializable implementieren - vielleicht könntest du deine save-Funktion also dahin erweitern, dass es nicht allgemeine Objects, sondern nur Serializables entgegennimmt...

Jedenfalls möchtest du jetzt den Krams wieder aus der Datei haben. Also gleiches Spiel rückwärts: Wir haben ein Object reingesteckt, also holen wir uns mit der load-Fkt ein Object wieder raus.
Und da wir ja wissen (oder zu wissen glauben), dass ein Array drinsteckt, formen wir das anschließend wieder in ein Array um...

So weit klar?

mfg,

RoCMe
 
Zurück