Newsgroup: it.comp.java
Titolo: Problema serializzazione

Salve a tutti...
Ho un problema con la serializzazione, probabilmente mi sfugge qualche
concetto essenziale.
Ho un file in cui ho serializzato una serie di oggetti di tipo
(Impiegato). So che sono stati scritti correttamente, perché
rileggendoli uno ad uno riesco a recuperarli.
Il mio problema è questo: questo file in cui sono serializzati gli
oggetti (Impiegato) deve simulare una query a database. Ossia, invece
di eseguire una connessione a database e recuperare i dati, io devo
leggere uno ad uno dal file questi oggetti ed inserirli in una List.
Il problema è, però, che non so a priori quanti saranno questi
oggetti! Perciò  non riesco a scrivere una condizione di terminazione
del ciclo di letture. Posto un frammento di codice:
  import packages.Impiegato;
  [...]
  java.util.List impiegati;
  Impiegato imp;
  [...]
  int returnVal = chooser.showOpenDialog(this);
  if (returnVal == JFileChooser.APPROVE_OPTION) {
 
  // Il file scelto è aperto in lettura per oggetti
  ObjectInputStream in = new ObjectInputStream(
                             new FileInputStream(
                             chooser.getSelectedFile().getName()));
  while( // ci sono ancora oggetti nel file)
  {
    Impiegato imp = (Impiegato)in.readObject();
    impiegati.add(imp);
  }
 
Ma quale condizione posso usare? La classe ObjectInputStream non ha un
metodo del tipo boolean Stream.EOF(), e quindi non so come fare...
Avevo provato una cosa del tipo:
  while((imp=(Impiegato)in.readObject()) != null)
  {
    impiegati.add(imp);
  }
  System.out.println("Pippo");
  System.out.println(impiegati.isEmpty());
  [...]
Ma non sono riuscito ad ottenere nulla; in particolare, il metodo non
arriva mai a stampare la parola "Pippo" sulla console; immagino che
esca prima con l'eccezione IOException...
Come posso fare?
So che una possibile soluzione è serializzare direttamente la lista, e
poi recuperarla con un'unica lettura, ma preferisco leggere una serie
di oggetti da file. C'è un modo per sapere se ci sono ancora oggetti
da leggere senza lanciare un'eccezione, che mi farebbe necessariamente
uscire dal metodo (e non posso, perché devo compiere altre
operazioni)?
Grazie a chi mi può dare una mano!
Marco
xprofx(AT)katamail_punto_com

 del ciclo di letture. 
Per esempio, scrivi per prima cosa un oggetto contenente nome e tipo degli 
oggetti a seguire. Oppure usa un oggetto "marcatore" (e instanceof per 
verificare il tipo runtime dopo readObject())
-- 
You dont know what to do when you dont know what you're doing.
http://space.tin.it/computer/csadun

Ciao, Marco!
Il giorno 23/03/2004 alle ore 10:48 hai scritto:
 MB> Ma non sono riuscito ad ottenere nulla; in particolare, il metodo non
 MB> arriva mai a stampare la parola "Pippo" sulla console; immagino che
 MB> esca prima con l'eccezione IOException...
Appunto, metti il ciclo di lettura in un blocco try / catch e quando viene
sollevata l'eccezione sai che il ciclo e' finito.
Se al momento della scrittura del file sai quanti oggetti devi scrivere puoi
inserire come primo elemento un int che rappresenta il numero di oggetti
scritti, lo potrai poi utilizzare in lettura per sapere quanto leggere.
Comunque se vuoi un consiglio evita la serializzazione degli oggetti e'
troppo critica, basta cambiare una virgola che non si e' piu' in grado di
leggere quello che che e' stato scritto. Usa un file di testo o un documento
XML, e' molto meglio.
Bye
-- 
Marco Maccaferri
MaccaSoft - 
http://www.maccasoft.com

 metodo del tipo boolean Stream.EOF(), e quindi non so come fare...
Su eof la readObject lancia una ObjectStreamException con il campo EOF 
eguale a true.
Quindi:
   while(true){
    Impiegato imp = null;
    try {
      imp = (Impiegato)in.readObject();
    } catch(OptionalDataException ode) {
      if(ode.EOF)
        break; // esce dal while
      // qui gestisci gli altri casi
    }
    catch(Exception e) {
       // qui gestisci le altre exception
    }
    impiegati.add(imp);
   }
Ah... dimenticavo...:
   leggi la documentazione prima di postare domande a cui
   io ho risposto semplicemente leggendo la documentazione....
 
http://java.sun.com/j2se/1.4.2/docs/api/java/io/ObjectInputStream.html
- Dario

XML, e' molto meglio.
Uhm... E a che serve allora la serializzazione? Per i documenti XML mi
devo documentare, non me ne intendo granché...
Ciao e grazie
Marco
xprofx(AT)katamail_punto_com

 altre operazioni)?
Magari non è chiarissimo, ma dovrebbe farti capire che le eccezioni,
caro Dario, le ho considerate (e sai come ho fatto a farlo? Eh già,
leggendo la documentazione!!)
In effetti, la soluzione che avevo adottato per mio conto, è
sostanzialmente simile alla tua, identificatori esclusi, tranne per il
fatto che non avevo pensato, da neofita, che l'eccezione non esce da
tutto il metodo, ma solo dal blocco try.
Però come ho scritto, io chiedevo se c'era un modo per sapere se ci
sono ancora oggetti da leggere SENZA lanciare un'eccezione...
Grazie per l'aiuto, ma se leggessi attentamente ciò che scrivono gli
altri, forse non li accuseresti di non leggere documentazione che
hanno letto. :)
Grazie!
Marco
xprofx(AT)katamail_punto_com

Ciao, Marco!
Il giorno 23/03/2004 alle ore 16:33 hai scritto:
 MB> Solo che non mi sembra molto elegante utilizzare il gestore delle
 MB> eccezioni per completare un task che svolgo nel metodo principale. In
 MB> questo caso è sufficiente, forse, ma in generale?
Certo non e' elegante, ma non se non c'e' altro modo...
 MB> mi interessava però una metodologia generale.
Beh dipende da quanto generale la vuoi. Se accedi ad un database le relative
classi ti ritornano se i record sono terminati o no, se leggi da un file
idem, se leggi da un socket altrettanto. In genere il metodo c'e', ma
probabilmente hai scelto di simulare con l'unico metodo che non permette di
sapere quando e' finito il file (in realta' lo permette perche' solleva
l'eccezione, basta gestirla).
 MB> Uhm... E a che serve allora la serializzazione?
Per come e' implementata in Java a mio parere non serve a niente.


 hanno letto. :)
I'm sorry.
- Dario

 devo documentare, non me ne intendo granché...
In effetti c'e' un modo di serializzare direttamente in XML, anche se non 
e' difficile farlo da se'.
http://java.sun.com/j2se/1.4.2/docs/api/java/beans/XMLEncoder.html
Se invece vai per il fai-da-te, qui trovi classi che ti consentono di 
scrivere SAX handlers separati per "porzioni" di XML (dipendente per 
esempio dal nome del tag) in modo da permettere file di configurazione in 
cui gli handler per certi elementi siano "pluggabili" (in opposizione ad 
avere un grosso handler monolitico). Ovvio che questo ti fara' senso solo 
quando ti indendi un po' piu' di XML. :)
http://sadun-
util.sourceforge.net/api/org/sadun/util/xml/configuration/package-
summary.html


l'eccezione, basta gestirla).
Beh... Adesso sto parlando di teoria della programmazione. Non credo
sia "corretto" al 100% quello che dici TEORICAMENTE parlando.
Voglio dire che la gestione delle eccezioni, e le eccezioni stesse,
dovrebbero essere un modo per gestire degli errori "inaspettati"
dell'algoritmo; un modo per trattare errori che si verificano a
runtime, ma estranei all'algoritmo.
Utilizzarle per svolgere compiti propri dell'algoritmo di soluzione
non mi sembra la cosa migliore, anche se poi agli effetti pratici
funziona.
Ormai ho strutturato il codice in questa maniera e proseguirò così, ma
se lo avessi saputo prima sarei andato per un'altra strada...
Grazie comunque!
Marco
xprofx(AT)katamail_punto_com

 
Ma scusa, che c'e' di male in oggetti marcatori?
cont=false;
while(cont) {
 Object obj = objStream.readObject();
 if (obj instanceof EndMarker) cont=false;
 else ...
