Newsgroup: it.comp.programmare.win32
Titolo: [MFC] Serialization

Ciao a tutti,
Sto cercando di salvare degli oggetti su disco... ma non riesco...
Ho applicato le funzionalita' di serialization alla mia classe e poi
faccio cosi':
CArchive ar(&file,CArchive::store);
mioOggetto.Serialize(ar);
Il file viene scritto correttamente (e il contenuto e' giusto) ma se
poi vado a scrivere un secondo oggetto sul file questo mi sostituisce
il primo !
Come si fa ad aggiungere altri oggetti ad un file ? una specie di
database rudimentale insomma...
Per caso devo creare un CObArray e poi serializzare quello ?
O magari ci sono metodi alternativi piu' semplici per scrivere e
leggere delle entry come in un database estremamente semplice ?
Grazie a tutti !
-- 
Lorenzo

Per caso devo creare un CObArray e poi serializzare quello ?
Ho risolto (alle 01.00 di notte...) con un template CArray:
CArray < mioOggetto, mioOggetto & > arrayOggetti;
Ci aggiungo gli oggetti:
arrayOggetti.Add( mioOggetto );
 e poi li scrivo tutti insieme su disco con:
CArchive archive (&file, CArchive::store);
arrayOggetti.Serialize(archive);
Per leggere l'array tutto in una volta si fa semplicemente:
CArchive archive (&file, CArchive::load);
arrayOggetti.Serialize(archive);
pero' visto che l'array contiene puntatori ad oggetti bisogna fare
l'override della funzione SerializeElements utilizzata internamente da
CArray, altrimenti salverebbe su disco dei puntatori:
void AFXAPI SerializeElements(CArchive &ar, mioOggetto * pOggetto, int
nCount)
{
	for ( int i = 0; i < nCount; i++, pCard++ )
	{
		pOggetto->Serialize(ar);
	}
}
Ciao a tutti !
-- 
Lorenzo

Non era necessario arrivare ai template; dovevi semplicemente controllare
di non aver distrutto l'archivio o il file prima di salvare il secondo
oggetto.
Ciao
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

oggetto.
Ah ! Ho capito, in effetti l'apertura e la chiusura dell'archivio e
del file erano nella stessa funzione dove facevo la scrittura del
singolo oggetto. Ora pero' scattano le domandine... ;)
Domanda 1: in questo modo e' possibile tenere il file e l'archivio
aperti per tutta la durata del programma e farci letture e scritture
sopra ? oppure devo fare tutte le scritture insieme e separarle dalle
letture ? ad occhio direi la seconda visto che l'archivio lo apro con
i parametri CArchive::load o CArchive::store...
Domanda 2: se apro un file che contiene gia' dei record, per
aggiungerne uno nuovo in coda devo copiare tutti i record in memoria e
riscriverli da capo insieme a quello nuovo ?
Domanda 3: se faccio un ciclo che mi legge tutti i record presenti nel
file, come faccio a sapere quando arrivo in fondo ? non mi sembra che
CArchive abbia una funzione che mi dica se sono alla fine
dell'archivio. Mi viene in mente che potrei calcolare quanti record ci
sono nel file sapendo la dimensione in byte del singolo record, ma non
so quanti byte extra aggiunge CArchive alle variabili che ci metto
io... e poi quando vado a scrivere oggetti CString che hanno
dimensione variabile e' un casino... al massimo potrei tenere un file
extra con il numero dei record salvati nel file... 
Ciao e grazie !
-- 
Lorenzo

 Ciao e grazie !
Figurati; tanto ho solo 17 anni e un c***o da fare... :D


Dimenticavo: se preferisci puoi usare CTypedPtrArray anziché
CTypedPtrList; la differenza sta nel diverso meccanismo di gestione degli
elementi: un array è un unico blocco di memoria contenente tutti gli
elementi, i quali sono riferibili tramite un indice; una lista invece è
costituita da elementi sparsi nella memoria, e ogni elemento viene
associato ad un puntatore all'elemento precedente e uno a quello
successivo.


myFile.Seek(0, CFile::end);
Questo gia' lo faccio per un file che sto gestendo a livello di byte
(la struttura e' statica), apro il file e poi mi sposto avanti e
indietro con Seek e poi con Read e Write leggo e scrivo gruppetti di
byte.
Ora che devo salvare dei record misti (stringhe, int, array di byte)
il giochino con Read a Write su un file di tipo CFile diventa troppo
complicato e quindi sono andato a cercare la serializzazione.
Per come l'ho implementato adesso funziona ma non e' proprio ottimo
(per essere buoni), in pratica all'inizio del programma creo il CFile,
il CArchive, faccio un serialize per leggere tutto il file in un
template CArray e poi chiudo sia il CFile che il CArchive. Durante il
programma modifico gli elementi dell'array e poi alla fine (o in altri
momenti particolari) ricreo CFile e CArray e faccio un nuovo serialize
per scrivere tutto l'array su disco... funziona (anche perche' il file
ha per ora una decina di record da circa 50 byte ciascuno), ma non e'
proprio bello ;)
-- 
Ciao !
Lorenzo

 proprio bello ;)
Perché no? Fintanto che non hai un numero troppo elevato di record, qual è
il problema? Il problema si presenta quando hai un numero di record molto
elevato (calcoliamo ad es. 1.000.000 record, cioè 50 megabyte se non
erro); in tal caso forse sarà meglio che eviti di serializzare chiamando
la Serialize di una classe template, e serializzi invece per conto tuo, in
modo tale da conoscere e poter calcolare con esattezza la posizione di
ciascun record e da poter gestire il file pointer a tuo piacere.
