Swing Laden von serialisierten Objekten (invalid type code AC))

Blagg Dogg

Mitglied
hi,

ich bin gerade dabei, ein adressbuch zu schreiben (zu übungszwecken) das soll so ablaufen, dass ich die eingegebenen adressen als adress-objekte seialisiere und später wieder deserialisiere. und genau hier ist das problem: wenn ich die objekte wieder lesen will, wird die erste adresse gut gelesen und dann kommt die folgende fehlermeldung:

java.io.StreamCorruptedException: invalid type code: AC
invalid type code: AC
at java.i😵bjectInputStream.readObject0(Unknown Source)
at java.i😵bjectInputStream.readObject(Unknown Source)
at data.ReadData.deserealize(ReadData.java:26)
at main.MainBook.buildCenter(MainBook.java:102)
at main.MainBook.create(MainBook.java:54)
at client.MyClient.main(MyClient.java:21)


hier mal kurz die zwei klassen:
folgende klasse liest die daten und gibt diese als arraylist zurück:
Java:
package data;

import java.io.*;
import java.util.ArrayList;

import utilities.MyMsg;

import main.Adresse;

public class ReadData {
	
	@SuppressWarnings("finally")
	public ArrayList<Adresse> deserealize(){
		ArrayList<Adresse> result = new ArrayList<Adresse>();
		
		try {
			FileInputStream fin = new FileInputStream("data2.ser");
			ObjectInputStream oin = new ObjectInputStream(fin);
			
			while(true){
				try{
					//	Adresse temp = (Adresse)oin.readObject();
					
					Object o = oin.readObject();
					if(o instanceof Adresse){
						
						Adresse temp = (Adresse)o;
						result.add(temp);
					}	
				} catch (EOFException e) {
					break;
				}
			}
			
			
			oin.close();
	
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			new MyMsg("Keine Daten gefunden - Bitte Neue Daten anlegen").setVisible(true);
		}
		
		catch (IOException e){
			e.printStackTrace();
			System.out.println(e.getMessage());
		}
		
		finally{
			return result;
			
		}
		
	}

}

...und folgende ist das hauptbuch mit der jtable in der man dann namen auswählen kann (auszug):
Java:
	private JPanel buildCenter(){
		JPanel p = new JPanel(new BorderLayout());
		
		adressen=new ReadData().deserealize();

		
		p.setBorder(BorderFactory.createTitledBorder("Meine Kontakte"));
		
		final JList list = new JList(adressen.toArray()) {
		    public String getToolTipText(MouseEvent evt) {
		    	int index = locationToIndex(evt.getPoint());
		        return ((Adresse)adressen.toArray()[index]).vorname + " " + ((Adresse)adressen.toArray()[index]).name + " (" + ((Adresse)adressen.toArray()[index]).gruppe + ")";
		    }
		};;
		
		p.add(list);
		

		JButton details = new JButton("Details");
		details.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				if (list.getSelectedIndex()==-1) new MyMsg("Bitte erst Namen wählen").setVisible(true);
				else new ShowAdress((Adresse) adressen.toArray()[list.getSelectedIndex()]).setVisible(true);
				
			}
		});
		
		JButton delete = new JButton("Kontakt entfernen");
		delete.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				if (list.getSelectedIndex()==-1) new MyMsg("Bitte erst Namen wählen").setVisible(true);
				
				//Sonst Abfrage
			}
		});
		
		JPanel button = new JPanel(new FlowLayout(FlowLayout.CENTER));
		button.add(details);
		button.add(delete);
		p.add(button, BorderLayout.SOUTH);

		
		return p;
	}

könnt ihr mir da helfen, wäre super nett 😛

ps: ich muss mit sicherheit auch noch irgendwo invokeLater einbauen, weiß aber nicht wo...
 
Abgesehen von dem Problem, wäre es nicht sinnvoller für ein Adressebuchprogramm eine Datenbank zu nutzen?

Du schreibst alle Adressen in eine Datei? "invalid type code: AC" deutet lt. java - StreamCorruptedException: invalid type code: AC - Stack Overflow darauf hin, dass du in der einen Datei mehrere Header hast. Darum wäre vielleicht eher interessant, wie du die Adressen serialisierst.


Auch würde ich deine deserialize Methode etwas anders schreiben.
Java:
    public ArrayList<Adresse> deserealize(){
        ArrayList<Adresse> result = new ArrayList<Adresse>();
        
        ObjectInputStream oin = null;
        try {
            FileInputStream fin = new FileInputStream("data2.ser");
            oin = new ObjectInputStream(fin);
            while(true){
                try{
                    //  Adresse temp = (Adresse)oin.readObject();
                    
                    Object o = oin.readObject();
                    if(o instanceof Adresse){
                        
                        Adresse temp = (Adresse)o;
                        result.add(temp);
                    }   
                } catch (EOFException e) {
                    break;
                }
            }
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            new MyMsg("Keine Daten gefunden - Bitte Neue Daten anlegen").setVisible(true);
        }
        catch (IOException e){
            e.printStackTrace(System.err);
            System.out.println(e.getMessage());
        }
        finally{
          try {
            if (oin != null) {
              oin.close();
            }
          } catch (IOException e) {
            //nevermind
          }
        }        return result;
    }
 
das ist meine klasse, die die adressen in die datei schreibt:

Java:
package data;

import java.io.*;

import main.*;
import utilities.MyMsg;

public class WriteData {
	
	public void serialize(Adresse a){
		try {
			ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("data2.ser", true));
			out.writeObject(a);
			
			
		out.close();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			new MyMsg("Fehler beim Anlegen der Datei.").setVisible(true);
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			new MyMsg("Fehler beim Schreiben der Datei.").setVisible(true);
			e.printStackTrace();
		}
	}

}

dieses true beim objectoutputstream bedeutet doch anhängen, falls datei existiert, oder?

edit: hierbei wird keine exception geworfen.
 
Ja, das
Code:
true
ist das Problem. Damit werden neue Daten an die Datei angehängt, aber bei der Serialisierung werden auch immer Header-Informationen geschrieben, die stehen dann mehrfach in einer Datei. Beim Deserialisieren verschluckt sich der ObjectInputStream an den zusätzlichen Header-Informationen, die mitten in der Datei stehen, wo sie wohl nicht hingehören.

Du müsstest wohl immer alle Adressen wieder neu serialisieren. Oder eben eine Datenbank. Wenn du noch nicht mit Datenbanken gearbeitet hast, hier hat das schonmal jemand mit einem Adressbuch versucht: Java Swing Address Book
 

Neue Themen


Zurück
Oben