Newsgroup: it.comp.java
Titolo: problema con la serializzazione

Salve, e' la prima volta che scrivo in questo ng quindi un saluto a tutti.
0.)
il mio problema e' semplice, quando scrivo oggetti in un 
ObjectOutputStream, non tutti nello stesso momento, quando devo leggerli 
mi lancia una IOException (precisamente 
java.io.StreamCorruptedException) quando tento di leggere il secondo 
oggetto.
il codice che scrive:
// nick e passwd sono 2 String
ObjectOutputStream out = null;
FileOutputStream fos = null;
	try{
//associo lo stream out al file swaccount, che esiste in Append!
		out = new ObjectOutputStream(new FileOutputStream("swaccounts",true));
//Customer e' una class che tiene nick/passwd e statistiche..
		out.writeObject(new Customer(nick,passwd));
		out.close();
	}catch(IOException e){...}
il codice che legge:
ObjectInputStream in = new ObjectInputStream(new 
FileInputStream("swaccounts"));
Customer a = (Customer)in.readObject();
//questa riga lancia l'eccezione
Customer b = (Customer)in.readObject();
Dove sto sbagliando? ho provato a scrivere piu' oggetti in una volta 
sola, e in questo caso riesco a leggerli senza problemi... ma purtroppo 
devo fare in questo modo. grazie.
1.) una domanda spero piu' interessante:
per gestire gli account e statistiche penso di usare jdbc + postgresql, 
ma voglio anche poter mantenere le statistiche nel caso in cui il db non 
sia disponibile, quindi salvare su file (il problema della 
serializzazione di prima).
creare un unico file di oggetti serializzati mi sento di escluderlo, un 
modo semplice sarebbe di creare un file con il nomeutente e salvare i 
dati dentro (per poi in seguito integrare il tutto col database una 
volta che torna disponibile).
Pensavo invece di usare una funzione Hash sul nomeutente per mappare 
utenti -> file, cosi da non avere troppi file sparsi e avere cmq una 
buona velocita' di accesso. qualche consiglio?
grazie ancora
Saluti

 ha scritto nel
messaggio news:X123c.15857$z23.7...@news3.tin.it...


 inviare) ?
Si l'ho fatto non riuscirei a serializzarli, il file lo scrive (quando 
aggiungo oggetti, aggiunge "dati" al file, il problema e' leggerlo.
il primo oggetto riesco a leggerlo, lo stream mi si corrompe con il secondo.

 ha scritto nel messaggio
news:8v23c.18689$O31.8...@news4.tin.it...

Ho avuto il tuo stesso problema il mese scorso...
In pratica devi scrivere tutti i tuoi dati senza riaprire lo stream...
quindi apri lo stream, scrivi tutto e chiudi lo stream.
Ovviamente la cosa non sempre è realizzabile, ma di modi per aggirare il
problema ce ne sono, ma tutti assolutamente non eleganti e poco performanti.
1) Ogni volta crei un file diverso, senza aprirne uno già esistente.
Ovvimente per farlo al tuo file darai un nome seguito da un numero in modo
tale che se puoi sempre crearne uno successivo.
2) Apri uno stream in lettura, ed uno in scrittura (ma su altro file), copi
tutto quello che c'è nel file in letura in quello in scrittura e poi
continui ad aggiungere quello che ti serve.
In entrambi i casi eviti di aprire più volte stream e scrivere poche cose
ogni volta sullo stesso file creando il problema.
Così funziona, se devi fare una cosa "casalinga" và più che bene, ma non lo
farei per applicazioni più complesse anche perchè, come ho detto, vanno a
farsi benedire eleganza e performance.
/* Delvy */

 
O_O ma davvero ?
ma non capisco... non mi sembra cosi' irrealizzabile poter aggiungere in 
append al file. cosi' e' scomodissimo!
quindi anche per sostituire un oggetto immagino bisogna riscrivere 
tutto... mi sembra assurdo :(

forse un'altra soluzione casalinga è:
import java.io.*;
public class Server {
  File file = new File("customers.dat");
  FileOutputStream fos = null;
  public Server() {
    try {
      fos = new FileOutputStream(file, true);
    }
    catch (FileNotFoundException ex) {
    }
  }
  private void scriviA() {
    ObjectOutputStream oos1 = null;
    try {
      oos1 = new ObjectOutputStream(fos);  // <--- reinizializzi
      oos1.writeObject(new Customer("Andrea", "xxx"));
      oos1.flush();
    }
    catch (IOException ex1) {
      ex1.printStackTrace();
    }
  }
  private void scriviB() {
    ObjectOutputStream oos2 = null;
    try {
      oos2 = new ObjectOutputStream(fos); // <--- reinizializzi
      oos2.writeObject(new Customer("Marco", "yyy"));
      oos2.flush();
      oos2.close();
    }
    catch (IOException ex1) {
      ex1.printStackTrace();
    }
  }
  private void leggiTutto() {
    try {
      FileInputStream fin = new FileInputStream("customers.dat");
      ObjectInputStream oin = new ObjectInputStream(fin);
      Customer c1 = (Customer) oin.readObject();
      System.out.println("Letto 1 : " + c1+ " ");
      oin = new ObjectInputStream(fin);   // <--- reinizializzi
      Customer c2 = (Customer) oin.readObject();
      System.out.println("Letto 2 : " + c2);
      oin = new ObjectInputStream(fin);   // <--- reinizializzi
      Customer c3 = (Customer) oin.readObject();
      System.out.println("Letto 3 : " + c3);
    }
    catch (ClassNotFoundException ex2) {
      ex2.printStackTrace();
    }
    catch (IOException ioe2) {
      ioe2.printStackTrace();
    }
  }
  public static void main(String[] args) {
    Server s = new Server();
    s.scriviA();
    s.scriviA();
    s.scriviB();
    s.leggiTutto();
  }
}
import java.io.*;
public class Customer implements Serializable {
  String nome, passw;
  public Customer(String name, String pwd) {
    nome = name;
    pwd = passw;
  }
  public String toString() {
    return "Nome: "+ nome + " Pwd: " +passw;
  }
}
in pratica OGNI volta che devi aggiungere un Customer reinizializzi
l'OutputStream
(ho messo due stream con nomi diversi ma non è quello il punto)
ed OGNI volta che devi leggere reinizializzi l'inputStream...
quindi non puoi scrivere 1 oggetto, poi tre oggetti, ecc... ma sempre uno
alla volta
nemmeno questa soluzione è molto elegante ( e nemmeno efficiente, ma cmq
l'efficienza è
da valutare nel complesso, molto probabilmente non sarà questo il punto
critico)

 
thx reinizializzando ObjIS funziona (ObjOS non serve reinizializzarlo)
in ogni caso non ne capisco proprio il motivo! davvero non mi riesco a 
dare una spiegazione.
grazie a tutti