ObjectInputStream

大兔子大兔子 提交于 2019-12-12 03:57:36

问题


I'm looking for how to use ObjectInputStream for a university project. I found a lot of things but I don't know why I can't succeed with it. Worst, I have more and more warnings.

Here are my three classes:

public class Contact implements Comparable<Contact>
{
private String nom;
private String prenom;
private int numTel;
private static int nbContacts;
private int numContact;

public Contact(String nom, int tel) //Constructeur nom et numero
{
    System.out.println(this.numTel);
    this.numTel = tel;
    System.out.println(this.numTel);
    this.nom = nom;
    this.numContact=++nbContacts;
}

public Contact(String nom)  //Constructeur Nom
{
    this.nom = nom;
    this.numContact=++nbContacts;
}

public Contact(String nom, String prenom, int tel) //Constructeur Nom, prenom, numero
{
    this.numTel = tel;
    this.nom = nom;
    this.prenom = prenom;
    this.numContact=++nbContacts;
}

public String getNom()
{
    return this.nom;
}

public String getPrenom()
{
    return this.prenom;
}

public int getTelephone()
{
    return this.numTel;
}

public int getNumContact()
{
    return this.numContact;
}

public void setNom(String nom)
{
    this.nom = nom;
}

public void setNumTelephone(int num)
{ 
    this.numTel = num;
}

public boolean equals(Contact contact)
{
    if(!this.nom.equals(contact.getNom()))
    {
        return false;
    }
    if(this.numTel!=contact.getTelephone())
    {
        return false;
    }
    return true;
}

public int compareTo(Contact contact)
{
    return (Integer.valueOf(this.nom) - Integer.valueOf(contact.getNom()));
}   
public String toString()
{
    String s = this.numContact + ") ";
    s+= String.format ( "%-10s", "NOM : ")  + this.nom;
    if(this.prenom != null)
    {
        s+=" | " + String.format ( "%-10s", "PRENOM : " )  + this.prenom ;
    }
    if(this.numTel != 0)
    {
        s+=  " : " + this.numTel;
    }           
    s += "\n";      
    System.out.println(this.nom);
    return s;
}
}

next

import java.util.ArrayList;
import java.util.List;
import java.io.*;
import java.util.Collections; 
public class Repertoire 
{
    private ArrayList<Contact>alContact;

public Repertoire()
{
    alContact = new ArrayList<Contact>();
    this.getData();
}

public String toString() 
{
    String s = "";
    for ( int cpt = 0; cpt < alContact.size(); cpt++ )
    {
        s += alContact.get(cpt).toString() + "\n";
    }
    return s;
}

public void addContact(String nom, int tel) //Constructeur nom et numero
{
    alContact.add(new Contact(nom, tel));
    this.sauvegarder();
}

public void addContact(String nom)  //Constructeur Nom
{
    alContact.add(new Contact(nom));
    this.sauvegarder();
}

public void addContact(String nom, String prenom, int tel) //Constructeur Nom, prenom, numero
{
    alContact.add(new Contact(nom, prenom, tel));
    this.sauvegarder();
}


// Permet d'enregistrer dans un fichier .dat les éléments du répertoire 
private void sauvegarder()
{
    try
    {
        ObjectOutputStream out = new ObjectOutputStream ( new FileOutputStream ("Rep.txt") );
        out.writeObject ( alContact );
    }
    catch ( Exception e ) {}
}

public void getData() 
{
    FileInputStream fis = null;
    ObjectInputStream in = null;
    try 
    {
        fis = new FileInputStream("~/Rep.txt");
        in = new ObjectInputStream(fis);
        alContact = (ArrayList) in.readObject();
        in.close();
    } 
    catch (IOException ex) 
    {
        System.out.println("Bordel");
    } 
    catch (ClassNotFoundException ex) 
    {
        System.out.println("Gros Bordel");
    }
}
// Permet de recuperer les donnée dans un fichier txt
private boolean charger()
{
    try
    {
        System.out.println("Dedans");
        ObjectInputStream in = new ObjectInputStream ( new FileInputStream ("Rep.txt"));
        System.out.println("Dedans");
        alContact = (ArrayList<Contact>) in.readObject();
        System.out.println("Dedans");
    }
    catch ( Exception e ) 
    {
        System.out.println("Pas de fichier");   
        return false;
    }

    Collections.sort (alContact);
    return true;
}

}

And just a Test

public class Test
{
    public static void main(String[] args)
    {
        int tel;
        Repertoire rep = new Repertoire();
        /*System.out.println("Entrez le numero");
        tel = Clavier.lire_int();
        rep.addContact("José", tel);
        */System.out.println(rep);
    }
}

This program is a phone index. I try to save index into a .txt/.dat but when I can't put it into the program. I hope it's understandable.


回答1:


Your Contact class must implement Serializable in order to be serializable to save/read to/from InputObjectStream/OutputObjectStream.

From ObjectInputStream documentation:

Classes control how they are serialized by implementing either the java.io.Serializable or java.io.Externalizable interfaces

Implementing the Serializable interface allows object serialization to save and restore the entire state of the object and it allows classes to evolve between the time the stream is written and the time it is read. It automatically traverses references between objects, saving and restoring entire graphs.

Note that when you run the Repertoire#getData in your program and your file is empty, you won't load any data at all. So, it would be better to first save some data in it. You can do this to add some data:

public void setStartData() {
    Contact contact = new Contact("Luiggi", "Mendoza", 12345);
    List<Contact> lstContact = new ArrayList<Contact>();
    lstContact.add(contact);
    ObjectOutputStream out = null;
    try {
        out = new ObjectOutputStream(new FileOutputStream("Rep.txt"));
        out.writeObject(lstContact);
        out.flush();
    } catch (IOException e) {
        System.out.println("Error while saving data.");
        e.printStackTrace(System.out);
    } finally {
        if (out != null) {
            out.close();
        }
    }
}

Additional advices:

  • static fields won't be serialized when saving data on file.
  • The data would be serialized in the file, so even if you treat it as a text file, its contents won't be like in human readable text (at least that you speak Java Serializable language).
  • Every attribute in your Serializable class should be serializable as well. This means, if you have an object instance inside it, its class must implement the Serializable interface.
  • You can omit an attribute from serialization by adding the transient modifier.
  • IMPORTANT: If you save the data, change the class definition and try to load the data, you would get an error. Make sure your class has the same structure when serializing/deserializing it. Looks like you were running on this issue for the last errors.



回答2:


Watch the way you have overridden your equals method in Contact class.
Its parameter should be of Object type . It should be like this

public boolean equals(Object obj)
{
    if ( ! (obj instanceof Contact))
    return false;
    Contact contact = (Contact) obj;
    if(!this.nom.equals(contact.getNom()))
    {
        return false;
    }
    if(this.numTel!=contact.getTelephone())
    {
        return false;
    }
    return true;
}

Also make your Contact class Serialzable by implementing Serializable interface while defining the Contact class.

Your sauvegarder method should be like this:

private void sauvegarder()
{
    ObjectOutputStream out = null;
    try
    {
        out = new ObjectOutputStream ( new FileOutputStream ("Rep.txt") );
        out.writeObject ( alContact );
    }
    catch ( Exception e ) {}
    finally
    {
      if(out!=null)
      {
        try
        {
           out.close();//close the outputstream
        }catch(Exception ex){}
      }
    }
}

And your getData method should be like this:

public void getData() 
{
    FileInputStream fis = null;
    ObjectInputStream in = null;
    try 
    {
        fis = new FileInputStream("Rep.txt");//Why using ~/Rep.txt instead of Rep.txt?
        in = new ObjectInputStream(fis);
        alContact = (ArrayList<Contact>) in.readObject();
    } 
    catch (IOException ex) 
    {
        System.out.println("Bordel");
    } 
    catch (ClassNotFoundException ex) 
    {
        System.out.println("Gros Bordel");
    }
    finally
    {
      if(in != null)
      {
        try
        {
           in.close();
        }catch(Exception ex){}
      }
    }
}

And you are reading data from the file which does'nt exist because you haven't written anything till now so for demo you can change your constructor Repertoire in this way:

public Repertoire()
{
    alContact = new ArrayList<Contact>();
    addContact("John",879999);
    addContact("Micky",4333);
    sauvegarder();
    this.getData();
}

And change your Contact class declaration as follows:

public class Contact implements Comparable<Contact>,java.io.Serializable


来源:https://stackoverflow.com/questions/15687146/objectinputstream

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!