Autore Topic: ObjectInputStream  (Letto 618 volte)

Offline darios

  • Nuovo arrivato
  • *
  • Post: 18
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    samsung galaxy s2
  • Sistema operativo:
    windows 8
ObjectInputStream
« il: 10 Luglio 2014, 15:35:00 CEST »
0
Salve a tutti, sto programmando un'agenda per android, ho creato tutti i layout e sono arrivato al punto di salvare e caricare gli appuntamenti (oggetto da me creato).
Per caricare gli appuntamenti ho usato questo metodo
Codice (Java): [Seleziona]
private void caricaAppuntamenti() throws StreamCorruptedException, IOException {
                // TODO Auto-generated method stub
                if(new File(Environment.getExternalStorageDirectory().getPath()+"/"+data+".txt").exists()){
                FileInputStream fis = null;
                try {
                        fis = new FileInputStream
                                ( Environment.getExternalStorageDirectory().getPath()+"/"+data+".txt");
                } catch (FileNotFoundException e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                        Toast.makeText(this, "Impossibile trovare il file specificato", Toast.LENGTH_LONG).show();
                }
                ObjectInputStream in = new ObjectInputStream(fis);    

                try {
                        while (true)
                                listaAppuntamenti.add(((Appuntamento) in.readObject()));
                } catch (Exception e) {
                        System.out.println(e.toString());
                }
               
                adapter.notifyDataSetChanged();
               
                Toast.makeText(this, "Caricamento effettuato con successo!\n"+listaAppuntamenti.size()+" oggetti caricati!\n", Toast.LENGTH_LONG).show();
        }
        }
ma carica solo il primo appuntamento salvato nel determinato giorno e non tutti quelli salvati .
Qualcuno riesce a capire dove sta l'errore?

Offline Ohmnibus

  • Utente senior
  • ****
  • Post: 671
  • Respect: +143
    • Github
    • Google+
    • @ohmnibus
    • Mostra profilo
    • Lords of Knowledge GdR
  • Dispositivo Android:
    Huawei P9 Lite
  • Play Store ID:
    Ohmnibus
  • Sistema operativo:
    Windows 7 x64
Re:ObjectInputStream
« Risposta #1 il: 10 Luglio 2014, 16:44:39 CEST »
0
A parte che IMO ci sono delle anomalie nel codice (un while (true) senza break non si può vedere :-P ), dipende anche da come sono salvati questi dati...
Ohmnibus
Le mie app su Play Store

È stata trovata una soluzione al tuo problema? Evidenzia il post più utile premendo . È un ottimo modo per ringraziare chi ti ha aiutato.

Offline darios

  • Nuovo arrivato
  • *
  • Post: 18
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    samsung galaxy s2
  • Sistema operativo:
    windows 8
Re:ObjectInputStream
« Risposta #2 il: 10 Luglio 2014, 16:49:54 CEST »
0
questo è il codice di salvataggio
Codice (Java): [Seleziona]
public void salvaAppuntamento(EditText nomeAppuntamento, EditText luogoAppuntamento, TimePicker timep) throws IOException{
                Appuntamento nuovo= new Appuntamento(nomeAppuntamento.getText().toString(),
                                luogoAppuntamento.getText().toString(), timep.getCurrentHour().toString()+":"+timep.getCurrentMinute().toString());
                adapter.notifyDataSetChanged();
               
                FileOutputStream fos=null;
                try {
                        fos=new FileOutputStream(Environment.getExternalStorageDirectory().getPath()+"/"+data+".txt", true);
                } catch (FileNotFoundException e) {
                        // TODO: handle exception
                        Toast.makeText(Activity_due.this, "file non trovato", Toast.LENGTH_LONG).show();
                        e.printStackTrace();
                }
                ObjectOutputStream out=new ObjectOutputStream(fos);
                listaAppuntamenti.add(nuovo);
                for(Appuntamento appuntamento:listaAppuntamenti)
                out.writeObject(appuntamento);

                out.close();
                Toast.makeText(Activity_due.this, "Salvataggio effettuato con successo!\n"+listaAppuntamenti.size()+" oggetti salvati!", Toast.LENGTH_LONG).show();
        }
e questo funziona, perchè ho visto il file in cui salva gli appuntamenti, e salva tutti quelli che aggiungo. Per quanto riguarda il while (true) senza break, ho visto su alcune slides che si faceva così, ma non so se è questo l'errore

Offline Ohmnibus

  • Utente senior
  • ****
  • Post: 671
  • Respect: +143
    • Github
    • Google+
    • @ohmnibus
    • Mostra profilo
    • Lords of Knowledge GdR
  • Dispositivo Android:
    Huawei P9 Lite
  • Play Store ID:
    Ohmnibus
  • Sistema operativo:
    Windows 7 x64
Re:ObjectInputStream
« Risposta #3 il: 10 Luglio 2014, 17:09:56 CEST »
+1
Il while (true) senza break sicuramente non è il problema, ma non aiuta ad individuarlo perché si basa su un'eccezione per uscire dal ciclo. Quindi in pratica non sai se l'eccezione è avvenuta a seguito di un problema o perché doveva esserci.

Tra le best practices che leggo in rete, suggeriscono di aggiungere un oggetto null come ultimo elemento in scrittura, e leggere fino a che non si incontra un oggetto null.

Ossia, in scrittura:

Codice (Java): [Seleziona]
for(Appuntamento appuntamento:listaAppuntamenti) {
    out.writeObject(appuntamento);
}
out.writeObject(null);

ed in lettura:

Codice (Java): [Seleziona]
Object tmpObj;
while ((tmpObj = in.readObject()) != null) {
    if (tmpObj instanceof Appuntamento) {
        listaAppuntamenti.add(((Appuntamento)tmpObj));
    } else {
        throw new Exception("Oggetto non riconosciuto");
    }
}

in questo modo se hai un'eccezione sai che è perché qualcosa è andato storto.

Non so se questo risolve il tuo problema, ma comunque ti aiuta ad individuarlo.
Ohmnibus
Le mie app su Play Store

È stata trovata una soluzione al tuo problema? Evidenzia il post più utile premendo . È un ottimo modo per ringraziare chi ti ha aiutato.

Offline darios

  • Nuovo arrivato
  • *
  • Post: 18
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    samsung galaxy s2
  • Sistema operativo:
    windows 8
Re:ObjectInputStream
« Risposta #4 il: 10 Luglio 2014, 17:24:14 CEST »
0
Ohmnibus grazie per il tuo aiuto, ho provato a fare come mi hai scritto, ma non ho risolto nulla, carica sempre il primo appuntamento salvato. Non ci sono state eccezioni, l'unico errore che è comparso nel log :SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length

Offline Ohmnibus

  • Utente senior
  • ****
  • Post: 671
  • Respect: +143
    • Github
    • Google+
    • @ohmnibus
    • Mostra profilo
    • Lords of Knowledge GdR
  • Dispositivo Android:
    Huawei P9 Lite
  • Play Store ID:
    Ohmnibus
  • Sistema operativo:
    Windows 7 x64
Re:ObjectInputStream
« Risposta #5 il: 10 Luglio 2014, 17:35:34 CEST »
0
Prova a scrivere e leggere tutti gli appuntamenti in un colpo solo. Eviti anche il problema di aggiungere un evento nullo alla fine.

Scrittura:

Codice (Java): [Seleziona]
out.writeObject(listaAppuntamenti);
Lettura:

Codice (Java): [Seleziona]
listaAppuntamenti = (ArrayList<Appuntamenti>)in.readObject();
Ohmnibus
Le mie app su Play Store

È stata trovata una soluzione al tuo problema? Evidenzia il post più utile premendo . È un ottimo modo per ringraziare chi ti ha aiutato.

Offline darios

  • Nuovo arrivato
  • *
  • Post: 18
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    samsung galaxy s2
  • Sistema operativo:
    windows 8
Re:ObjectInputStream
« Risposta #6 il: 11 Luglio 2014, 09:08:00 CEST »
0
scrivendo il codice che mi hai detto, mi segna un errore di scrittura nel caricaAppuntamenti:
Codice (Java): [Seleziona]
- ArrayList<Appuntamenti> cannot be resolved to a type
        - Appuntamenti cannot be resolved to a type
        - Type safety: Unchecked cast from Object to
         ArrayList<Appuntamenti>
:(

Offline Ohmnibus

  • Utente senior
  • ****
  • Post: 671
  • Respect: +143
    • Github
    • Google+
    • @ohmnibus
    • Mostra profilo
    • Lords of Knowledge GdR
  • Dispositivo Android:
    Huawei P9 Lite
  • Play Store ID:
    Ohmnibus
  • Sistema operativo:
    Windows 7 x64
Re:ObjectInputStream
« Risposta #7 il: 11 Luglio 2014, 11:30:16 CEST »
0
Sì, un mio errore di battitura, è ArrayList<Appuntamento>, non ArrayList<Appuntamenti>.
Ohmnibus
Le mie app su Play Store

È stata trovata una soluzione al tuo problema? Evidenzia il post più utile premendo . È un ottimo modo per ringraziare chi ti ha aiutato.

Offline darios

  • Nuovo arrivato
  • *
  • Post: 18
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    samsung galaxy s2
  • Sistema operativo:
    windows 8
Re:ObjectInputStream
« Risposta #8 il: 11 Luglio 2014, 11:50:48 CEST »
0
ok, adesso non mi segna più l'errore, però non mi carica nulla, nemmeno il primo appuntamento come faceva prima. In più facendo in questo modo non riesco ad estrarre nemmeno il file in cui salva l'arraylist per controllare cosa ha realmente salvato. Nella console mi esce:
Failed to push selection: Local path doesn't exist.

Offline Ohmnibus

  • Utente senior
  • ****
  • Post: 671
  • Respect: +143
    • Github
    • Google+
    • @ohmnibus
    • Mostra profilo
    • Lords of Knowledge GdR
  • Dispositivo Android:
    Huawei P9 Lite
  • Play Store ID:
    Ohmnibus
  • Sistema operativo:
    Windows 7 x64
Re:ObjectInputStream
« Risposta #9 il: 11 Luglio 2014, 13:42:06 CEST »
+1
Ok, ho capito il problema.

Non puoi usare ObjectOutputStream in un file aperto in append, altrimenti ottieni quanto segue:

La prima volta che scrivi il file (quando hai solo un elemento) esso contiene

<DatiOggetto1><EOF>

Quando aggiungi un altro oggetto

<DatiOggetto1><EOF><DatiOggetto1><DatiOggetto2><EOF>

Quando aggiungi il terzo oggetto

<DatiOggetto1><EOF><DatiOggetto1><DatiOggetto2><EOF><DatiOggetto1><DatiOggetto2><DatiOggetto3><EOF>

in lettura ottieni sempre e solo il primo perché ObjectInputStream si ferma al primo <EOF>.


In pratica devi cambiare

Codice (Java): [Seleziona]
fos=new FileOutputStream(Environment.getExternalStorageDirectory().getPath()+"/"+data+".txt", true);
in

Codice (Java): [Seleziona]
fos=new FileOutputStream(Environment.getExternalStorageDirectory().getPath()+"/"+data+".txt", false);
in questo modo ogni volta che scrivi il file lo crei daccapo, ossia quando scrivi la prima volta:

<DatiOggetto1><EOF>

Quando aggiungi un secondo oggetto

<DatiOggetto1><DatiOggetto2><EOF>

Quando aggiungi il terzo oggetto

<DatiOggetto1><DatiOggetto2><DatiOggetto3><EOF>

e così via.

Stesso problema quando passi da Appuntamento ad ArrayList<Appuntamento>: l'app va in errore perché si aspetta di leggere un ArrayList<Appuntamento> ed invece si trova un Appuntamento.


Se incontri altri problemi torna ad utilizzare il precedente sistema di scrittura per singoli elementi:

Scrittura:

Codice (Java): [Seleziona]
for(Appuntamento appuntamento:listaAppuntamenti) {
    out.writeObject(appuntamento);
}
out.writeObject(null);

Lettura:

Codice (Java): [Seleziona]
Object tmpObj;
while ((tmpObj = in.readObject()) != null) {
    if (tmpObj instanceof Appuntamento) {
        listaAppuntamenti.add(((Appuntamento)tmpObj));
    } else {
        throw new Exception("Oggetto non riconosciuto");
    }
}
Ohmnibus
Le mie app su Play Store

È stata trovata una soluzione al tuo problema? Evidenzia il post più utile premendo . È un ottimo modo per ringraziare chi ti ha aiutato.

Offline darios

  • Nuovo arrivato
  • *
  • Post: 18
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    samsung galaxy s2
  • Sistema operativo:
    windows 8
Re:ObjectInputStream
« Risposta #10 il: 11 Luglio 2014, 14:25:41 CEST »
0
grazie mille, adesso funziona!! Solo una cosa, quando mi carica gli appuntamenti mi carica anche un "Appuntamento" che si chiama false, e se lo premo crasha l'app. Sai a cosa è dovuto e come posso evitare che compaia?

Offline Ohmnibus

  • Utente senior
  • ****
  • Post: 671
  • Respect: +143
    • Github
    • Google+
    • @ohmnibus
    • Mostra profilo
    • Lords of Knowledge GdR
  • Dispositivo Android:
    Huawei P9 Lite
  • Play Store ID:
    Ohmnibus
  • Sistema operativo:
    Windows 7 x64
Re:ObjectInputStream
« Risposta #11 il: 11 Luglio 2014, 14:30:58 CEST »
0
Non ho idea di cosa possa significare "un appuntamento che si chiama false".

Forse metti nell'ArrayList anche l'ultimo elemento, che è un "null" e serve solo per capire che sei arrivato alla fine.
Ohmnibus
Le mie app su Play Store

È stata trovata una soluzione al tuo problema? Evidenzia il post più utile premendo . È un ottimo modo per ringraziare chi ti ha aiutato.

Offline darios

  • Nuovo arrivato
  • *
  • Post: 18
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    samsung galaxy s2
  • Sistema operativo:
    windows 8
Re:ObjectInputStream
« Risposta #12 il: 11 Luglio 2014, 14:44:51 CEST »
0
ho risolto il problema del "false" che veniva caricato come ultimo elemento. Non mi sono accorto di una riga di codice che lo aggiungeva.
se invece volessi eliminare un singolo Appuntamento, come dovrei fare? perché esiste un metodo per eliminare il file creato, ma non ne ho trovati per eliminare singoli elementi.
« Ultima modifica: 11 Luglio 2014, 15:38:01 CEST da darios »

Offline Ohmnibus

  • Utente senior
  • ****
  • Post: 671
  • Respect: +143
    • Github
    • Google+
    • @ohmnibus
    • Mostra profilo
    • Lords of Knowledge GdR
  • Dispositivo Android:
    Huawei P9 Lite
  • Play Store ID:
    Ohmnibus
  • Sistema operativo:
    Windows 7 x64
Re:ObjectInputStream
« Risposta #13 il: 11 Luglio 2014, 16:43:19 CEST »
+1
Elimini l'elemento dall'ArrayList e riscrivi tutto il file
Ohmnibus
Le mie app su Play Store

È stata trovata una soluzione al tuo problema? Evidenzia il post più utile premendo . È un ottimo modo per ringraziare chi ti ha aiutato.

Offline darios

  • Nuovo arrivato
  • *
  • Post: 18
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    samsung galaxy s2
  • Sistema operativo:
    windows 8
Re:ObjectInputStream
« Risposta #14 il: 11 Luglio 2014, 16:44:56 CEST »
0
grazie mille, gentilissimo  :-)