Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 12

Discussione: [JAVA] serializzare

  1. #1
    Utente di HTML.it
    Registrato dal
    Sep 2004
    Messaggi
    143

    [JAVA] serializzare

    Salve a tutti, ho capito come funziona la serializzazione, ma non riesco a implementarla in modo diciamo lineare.
    Ho pensato di fare una classe Oggett, per avere un generico oggetto in una classe Utilizza che sarà quella coi metodi scrivi() e leggi(), nella classe Test richiamo le varie funzioni:

    codice:
    import java.io.*;
    public class Oggett implements Serializable
    {
    	private int valore;
    	private String nome;
    	
    	public Oggett()
    	{
    		valore = 0;
    		nome = null;
    	}
    	public Oggett(int v , String n)
    	{
    		valore = v;
    		nome = n;
    	}	
    }
    
    import java.io.*;
    public class Utilizza
    {
    	private Oggett ogg;
    	
    	public Utilizza()
    	{
    		ogg = new Oggett();
    	}
    	
    	public  Utilizza(int v,String n)
    	{
    		ogg = new Oggett(v,n);
    	}
    	
    	public void scrivi() throws ClassNotFoundException , IOException
    	{
    		ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("salvadato"));
    		out.writeObject(ogg);
    		out.close();
    	}
    	public void leggi() throws ClassNotFoundException , IOException
    	{
    		ObjectInputStream in = new ObjectInputStream(new FileInputStream("salvadato"));
    		Oggett ogg3 = (Oggett)in.readObject();
    	}
    }
    
    import java.io.*;
    public class Test
    {
    	public static void main(String [] args) throws Exception
    	{
    		int val = 4;
                    String parola = "Ciao";
    		Utilizza u = new Utilizza(val,parola);
    		
    		u.scrivi(); 
                    ?
                    ? 
    	}
    }
    Ecco, mi sono fermato a scrivere u.scrivi() in cui dovrebbe salvare l'oggetto di Oggett; ora il mio dubbio è questo: al fine di usare la serializzazione esattamente per lo scopo per cui è stata creata cosa devo fare, creare un nuovo oggetto Utilizza u2 e chiamare u2.leggi()? ma in questo modo avrò 2 oggetti che hanno le stesse informazioni, u e u2? Oppure devo farlo in altre parti del programma?
    Cioè in pratica non capisco la struttura del programma per utilizzare questa tecnica di persistenza dati.
    Ringrazio chiunque mi possa indicare soluzioni

  2. #2
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,304
    Diciamo che, solitamente, i metodi si implementano in modo diverso: tu hai dichiarato il metodo leggi() come void; questo significa che quel metodo legge i dati dal file e li salva da qualche parte in un oggetto interno (che però nel tuo metodo esiste solo lì e muore appena il metodo termina ).
    Generalmente, invece, il metodo leggi() si implementa in modo da ritornare l'oggetto letto dal file:
    codice:
    public Oggett leggi() {
       ObjectInputStream in = new ObjectInputStream(new FileInputStream("salvadato"));
       Oggett ogg3 = (Oggett) in.readObject();
       return ogg3;
    }
    In questo modo va utilizzate così:
    codice:
    Oggett o = u.leggi();
    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  3. #3
    Utente di HTML.it
    Registrato dal
    Sep 2004
    Messaggi
    143
    Si, hai ragione, il metodo deve restituire qualcosa in tutti i modi!!
    Però resta il problema che per esempio se io nel main di Test faccio Oggett og = u.leggi(); io mi ritrovo l'oggetto che è campo di u e con og che hanno gli stessi valori,quindi ho dei doppioni.
    Se chiudo il programma e poi lo riapro mi succede che ricreo le stesse cose, non è che faccio un ripristino da quello che posso capire!
    A questo punto mi chiedo: ma salvare in un file .txt e poi rileggerlo per ripartire da dove eravamo rimasti, come se avessi per esempio un archivio, oppure fare il metodo della serializzazione, non è la stessa cosa come concetto?
    Infatti avevo pure pensato di fare uno switch che controllasse se il file "salvadato" è vuoto faccio come nel codice sopra, altrimenti ricarico ciò che ho salvato. Ho capito male come si usa la serializzazione?

  4. #4
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,304
    Nessuno ti vieta di costruire due applicazioni diverse: una che salva sul file e l'altra che legge dal file. E' ovvio che se il salvataggio e la lettura avvengono all'interno della stessa applicazione con gli stessi dati si creano dei doppioni ed è abbastanza inutile, ma in generale non lo è: i file, infatti, servono proprio a questo!


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  5. #5
    Utente di HTML.it
    Registrato dal
    Sep 2004
    Messaggi
    143
    Quindi mi consigli per singole applicazioni di usare input/output con un file e se ci sono più applicazioni si può lavorare con la serializzazione?
    In effetti con una sola applizione non mi torna proprio, fa solo copie di dati già esistenti, mi sa che appesantisce solo il programma e niente più.

  6. #6
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,304
    Io non ho ancora capito di cosa tu abbia bisogno, però mi pare di capire che non hai le idee ben chiare: la serializzazione è il meccanismo che permette di salvare degli oggetti su file, di poterli trasmettere via rete, ecc... E' un meccanismo che permette agli oggetti di essere trattati per operazioni di Input/Output.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  7. #7
    Utente di HTML.it
    Registrato dal
    Sep 2004
    Messaggi
    143
    Sto solo facendo pratica con questo nuovo concetto che ho imparato da poco, solo che poi se le cose non si vedono all'atto pratico non mi pare sia il modo migliore per imparare, e in effetti dalla teoria alla pratica mi pare che vengano fuori un bel pò di problemi.
    In un progettino tempo fa ho usato un file.txt per fare un archivio, chiudevo il programma e alla riapertura controllavo se il file era non vuoto allora ricaricavo e creavo la struttura dati, sennò aspettavo solo degli input nuovi per creare sia la struttura dati che emorizzare man mano nel file ancora vuoto.
    Ora ho imparato che c'è pure la serializzazione, da come l'ho capita io potrei fare le stesse identiche cose che ho fatto in quel progettino usando la serializzazione. Poi per provare in un esempio molto più piccolo ho creato il codice postato sopra, da qui i problemi strutturale del mio esempio, il fatto che mi vengono solo doppioni ecc...
    Il mio scopo era solo questo: usare una prima volta il programma alla prima esecuzione, poi se si chiude e si riapre controllare se il file "salvadato" è non vuoto e caricare eventuali dati.
    Solo che come l'ho creato io mi sembra che serializzare serva a poco, in esecuzione fa solo doppioni e ad una nuova esecuzione fa le stesse identiche cose della prima volta, perchè non so come strutturare il programma.
    Purtroppo nei manuali si dice come si fa una cosa, ma gli esempi ben fatti sono rari, io invece credo che capire le regole sintattiche sia abbastanza semplice, è usare i mezzi di un linguaggio per fare un buon programma che mi sembra la cosa più difficile per chi vuol imparare a programmare.

    Ciao

  8. #8
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,304
    Mi sembra di capire che sei un autodidatta della programazione Java: molto bene, è il modo migliore per imparare (secondo me)!
    Solo che a volte l'aiuto di chi le cose le sa già è importante, se non indispensabile... per questo esistono dei corsi che insegnano (più o meno bene) la programmazione.

    Se vuoi possiamo parlare di questa serializzazione, cercando di riassumere i concetti più importanti il più semplicemente possibile.

    Cominciamo con un esempio, semplice semplice, di ciò che accade quando non si è in possesso di questo potente strumento: consideriamo di avere una applicazione che necessita di dati strutturati. Ad esempio, dobbiamo gestire una semplice biblioteca.

    La biblioteca prevede, ovviamente, di mantenere delle informazioni relative ai libri e per questo viene, generalmente, creata una classe che rappresenta proprio il libro. Una classe Libro, molto semplice, può essere la seguente:
    codice:
    public class Libro {
    
       private String titolo;           // Il titolo del libro
       private String autore;           // L'autore del libro
       private int annoPubblicazione;   // L'anno di prima pubblicazione
    
       public Libro(String titolo, String autore, int annoPubblicazione) {
          this.titolo = titolo;
          this.autore = autore;
          this.annoPubblicazione = annoPubblicazione;
       }
    
       public String getTitolo() { return titolo; }
       public String getAutore() { return autore; }
       public String getAnnoPubblicazione() { return annoPubblicazione; }
    }
    Questa classe, semplicissima, si usa in modo altrettanto semplice: si costruisce un oggetto Libro a partire dai dati essenziali richiesti dal costruttore:
    codice:
    String titolo = "Java, mattone dopo mattone";
    String autore = "Massimiliano Tarquini";
    int anno = 2001;
    
    Libro lib = new Libro(titolo, autore, anno);
    Ora supponiamo di dover salvare le informazioni riguardanti questo libro in un file (vediamo le cose in grande: la biblioteca avrà moltissimi libri da salvare su file!). Come possiamo fare? La cosa più ovvia e semplice è quella di creare un file di testo che contenga tutte le informazioni, magari ben formattate... qualcosa del genere, insomma:
    codice:
    Titolo libro                  Autore                    Anno Pubblicazione
    ----------------------------------------------------------------------------------
    Java, mattone dopo mattone    Massimiliano Tarquini     2001
    ...                           ...                       ...
    Bene... tutto questo ha i suoi vantaggi: abbiamo un bel file con tutte le informazioni che ci servono. Quand'è che sorgono i problemi? I problemi sorgono quando dobbiamo recuperare questi dati dal file: per poter ripopolare la nostra lista di oggetti Libro, dobbiamo leggere ciascuna riga del file, spezzettarla in base all'informazione che ci serve (Titolo, Autore e Anno) e poi ricreare un oggetto, passando queste tre informazioni al costruttore dell'oggetto.
    Non che sia un problema, ma a lungo andare potrebbe essere fastidiosa la cosa (soprattutto se abbiamo a che fare con molti campi da popolare).

    Per questo entra in soccorso la serializzazione: con questo strumento non dobbiamo più preoccuparci di recuperare ciascuna informazione singola dall'oggetto, salvarla sul file e, per contro, quando dovremo ricreare gli oggetti, non dovremo più andarci a pescare ciascuna informazione da passare al costruttore. Possiamo, semplicemente, salvare l'oggetto sul file. In questo modo, quando poi andremo a leggere il file, dovremo solo leggere gli oggetti salvati.

    Vediamo come si fa: è necessaio far implementare l'interfaccia Serializable alla classe che verrà salvata sul file. Tale interfaccia non presuppone l'implementazione di nessun metodo:
    codice:
    public class Libro implements Serializable {
    
       private String titolo;           // Il titolo del libro
       private String autore;           // L'autore del libro
       private int annoPubblicazione;   // L'anno di prima pubblicazione
    
       public Libro(String titolo, String autore, int annoPubblicazione) {
          this.titolo = titolo;
          this.autore = autore;
          this.annoPubblicazione = annoPubblicazione;
       }
    
       public String getTitolo() { return titolo; }
       public String getAutore() { return autore; }
       public String getAnnoPubblicazione() { return annoPubblicazione; }
    }
    Come vedi la classe non è stata toccata di una virgola, però ora non dovremo più andarci a salvare tutti i suoi campi, è sufficiente salvare sul file l'oggetto lib creato in precedenza:
    codice:
    String titolo = "Java, mattone dopo mattone";
    String autore = "Massimiliano Tarquini";
    int anno = 2001;
    
    Libro lib = new Libro(titolo, autore, anno);
    
    ObjectOutputStream oos = new ObjectOutputStream( new FileOutputStream("mioFile.dat") );
    oos.writeObject(lib);
    oos.close();
    A questo punto, quando dovremo ricreare tutti i libri salvati, sarà sufficiente leggere gli oggetti dal file:
    codice:
    ObjectInputStream ois = new ObjectInputStream( new FileInputStream("mioFile.dat") );
    Libro lib = (Libro) ois.readObject();
    Non abbiamo dovuto leggere tre informazioni per ricreare l'oggetto: abbiamo letto solo l'oggetto.

    Questo post non deve essere inteso come tutto ciò che la serializzazione permette di fare, sarebbe troppo riduttivo! E' solo un esempio di quanto aiuta tale strumento.
    Spero, per lo meno, di averti dati delle informazioni importanti su quali sono i vantaggi nell'utilizzo di questo strumento, piuttosto che la normale procedura di salvataggio di informazioni.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  9. #9
    Utente di HTML.it
    Registrato dal
    Sep 2004
    Messaggi
    143
    Esempio più che eccellente tra l'altro hai ripreso proprio una cosa simile al progettino che feci. Ho capito meglio la serializzazione, infatti dovetti fare cose molto complesse per memorizzare e riprendere i singoli campi.
    Il dubbio che resta è questo:
    allora, tu in fondo dici che recupero i dati con quelle semplici 2 righe, ok. Io però non capisco come organizzare il programma: i casi sono 2:
    1) se si tratta di far lavorare più applicazioni, metti per esempio in rete, non so come si fa e per ora lasciamo perdere, un giorno ci arriverò, ma mi è chiaro a grandi linee, una applizione ha nel main scrivi(), l,altra ha nel main leggi(), non esistono doppioni come invece nel mio esempio e siamo tutti felici e contenti.
    2) singola applicazione, io parto, scrivo il mio programma, devo fare uno switch però, perchè la lista, se il file è vuoto starà li in attesa di cominciare ad essere creata e estesa da vari input, ma se esiste già qualche oggetto nel file la devo creare al lancio del programma, giusto?
    Il fatto è che se non erro readObject() non restituisce null nel caso il file sia vuoto, forse perchè l'essere vuoto implica che non è stato ancora creato....
    In pratica, scrivere qualcosa che anche se mi è di esempio, lo potrei benissimo incastrare nel vecchio progettino e funziona, non so se ho reso l'idea del problema, adesso i metodi presi cosi sono chiarissimi, è a livello di programma che è poco chiaro.

    Molto gentile per tutte le spiegazioni che dai, GRAZIE

  10. #10
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,304
    Vediamo, allora di generalizzare: creaiamo una applicazione che chiede all'utente se desidera creare la lista dei libri da zero, oppure se ha un file da cui pescarla.

    In questo caso, quindi, il programma farà due cose diverse in base alla scelta dell'utente: se l'utente ha già creato, precedentemente, una lista di libri e vuole riaprirla, dovrà semplicemente fornire al programma il percorso del file da leggere.

    Per controllare se un file esiste, comunque, sono sufficienti queste poche righe di codice:
    codice:
    File f = new File("mioFile.dat");
    if (!file.exists()) {
       // Il file non esiste
    } else {
       // Il file esiste già.
    }
    In questo modo, se il file non esiste posso scegliere, ad esempio, di crearlo, se invece esiste già posso decidere di leggerlo.
    Esempio:
    codice:
    File f = new File("mioFile.dat");
    if (f.exists()) {
       // Il file esiste: lo leggo
       ObjectInputStream ois = new ObjectInputStream( new FileInputStream(f) );
       while (ois.available() > 0) {
          ...  // ciclo di lettura del file
       }
    }
    ...
    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.