Newsgroup: it.comp.programmare.win32
Titolo: File di testo che si corrompono

 
 
salve,
ho un problema un pò particolare.  Ho realizzato un'applicazione win32 (scritta in c++) che gira su un pc embedded con windows XP embedded, la cui unica particolarità che ci interessa è il files system readonly, in modo che questo pc embedded possa essere spento in qualunque momento semplicemente togliendo corrente (quindi senza fare la procedura di shotdown).
 
Tutto perfetto. Però ho il problema di dover scrivere un log.
Quindi ho fatto 2 partizioni: una con il sistema operativo che è readonly, mentre l'altra è libera. Su questa porzione libera viene scritto il log, che TEORICAMENTE viene scritto solo durante la lavorazione e MAI NESSUNO SPEGNE IMPROVVISAMENTE la macchina DURANTE LA LAVORAZIONE!
 
Eppure ogni tanto viene trovato questo maledetto file corrotto.
NOTARE BENE: questa partizione libera viene usata anche da altre applicazioni che girano e che scrivono, ma soltanto il mio log è soggetto a questo difetto.
A dire il vero nemmeno scommetto che sia davvero causato da uno spegnimento improvviso! Ma alcuni dettagli m'hanno fatto sospettare di questo e vorrei indagare (almeno per poter eventualmente escluderlo).
 
Il mio sospetto è che ,nonostante io usi la open(), write() e SUBITO la
close()  (non lo lascio mai aperto ad oltranza), windows non scriva immediatamente. Nonostante la close().
Altro sub-sospetto è che ciò avvenga a causa dei parametri che uso io nella 
open(). Parametri che però ho modificato spesso, durante i miei tentativi di risoluzione.
 
Altro dettaglio: quando il file si corrompe, lo trovo apparentemente vuoto...e invece è pieno di 0 binari (null), in quantità più o meno uguale a quella che dovrebbe essere se il contenuto fosse giusto.
 
La open la faccio cosi':
int fdStatistiche = open("nomefile", O_RDWR | O_TRUNC | O_CREAT | O_BINARY,   S_IREAD | S_IWRITE);
 
e ogni volta riscrivo l'intero contenuto (per questo c'è la O_TRUNC e O_CREATE), con una normale write(), di cui controllo il valore di ritorno che deve essere uguale alla lunghezza del byte scritti (e questo errore non è mai accaduto).
Immediatamente dopo:  	close(fdStatistiche);
 
 
Per funzionare, funziona parfettamente. Ma ogni tanto qualche cliente chiama perche' il file è corrotto.
Qui da me è successo solo 1 volta, e guardacaso dopo che era saltata la corrente per un temporale.
Ovvamente buttando giù all'improvviso volutamente, non ricapita più!
 
Buttate idee, grazie!  :)

 Immediatamente dopo:  	close(fdStatistiche);
 
Questo e' male, ti consiglio piuttosto di scrivere su di un nuovo file, 
magari usando la  GetTempFileName() per avere un nome unico e, 
successivamente, cancellare il vecchio file e rinominare il nuovo.
 
Il valore di ritorno della write() e' poco affidabile, ti dice solo che 
i byte sono stati scritti nella cache di sistema, ma non e' detto che 
siano stati effettivamente "scaricati" sul disco.

 ti consiglio piuttosto di scrivere su di un nuovo file, 
 
Oh!  Interessante!
Prima di tutto proverò a usare le API (CreateFile, ecc) con le giuste flag per non bufferizzare, anzichè le classiche funzioni open, write, close.
 
Poi mi hai fatto anche venire in mente un'altra questione: il disco è in realtà una flash  e quindi ha il problema che ,riscrivendo sempre la stessa area fisica, si consuma.
Anche per questo è meglio che faccia cosi': rinomino Log in Log_old, creo un nuovo file Log e cancello successivamente Log_old (quindi senza usare la MoveFile()).
Tra l'altro, se qualcosa si interrompe a metà, ho ancora Log_old dove i dati non sono aggiornati ma è meglio che niente.
 
Bene! Che bello aver qualcuno con cui poterne parlare!