Newsgroup: it.comp.lang.visual-basic
Titolo: System.IO.FileStream in scrittura e data di ultima modifica

Ciao a tutti,
in una applicazione (fw 3.5), utilizzo due oggetti di tipo 
System.IO.FileStream per fare una copia di un file. Utilizzo questi oggetti 
e non System.IO.FileInfo perche' ho la necessita' di sapere quanti bytes 
sono stati scritti.
Per fare la copia, leggo byte per byte dal sorgente, tramite il metodo 
ReadByte e quindi scrivo nella destinazione tramite WriteByte.
Una volta terminato il processo di lettura/scrittura, tramite due oggetti 
System.IO.FileInfo, uno per la sorgente ed uno per la destinazione, imposto 
la data di ultima modifica della destinazione uguale a quella della 
sorgente.
Il problema sorge nel malaugurato caso in cui il processo di copia venga 
interrotto per qualche motivo, ad esempio perche' salta l'energia elettrica 
o qualcuno dal task manager interrompe l'applicazione stessa.
Se cio' dovesse accadere, mi ritrovo con un file di destinazione piu' 
recente di quello sorgente, in quanto la data di ultima modifica equivale 
effettivamente al momento della copia.
Questo comportamento e', per l'applicazione che sto scrivendo, assolutamente 
da evitare, in quanto c'e' una logica di "sincronizzazione" dei files che va 
a controllare, appunto, quale file e' piu' recente.
Avete qualche idea su come poter ovviare al problema?
Ciao e grazie... Maurizio 

 Avete qualche idea su come poter ovviare al problema?
se sei su un OS come Windows 7 o Windows Server 2008 (non mi ricordo se 
deve essere un R2) puoi sfruttare la transazionalità del file system 
per garantirti il tutto o niente.
.m
-- 
Mauro Servienti
{C67C0157-5D98-4733-A75E-93CAEE4BADC8}
Microsoft MVP - Visual C# / MCTS
http://mvp.support.microsoft.com
blog @ 
http://milestone.topics.it
whynot [ at ] topics [ dot ] it

se sei su un OS come Windows 7 o Windows Server 2008 (non mi ricordo se
deve essere un R2) puoi sfruttare la transazionalità del file system
per garantirti il tutto o niente.
...
In realta' devo essere compatibile soprattutto con XP.
Sto pero' facendo delle prove impostando anche la data di creazione del file 
ad una temporanea, e riportarla a quella esatta dopo la conclusione della 
scrittura del file.
Sto incontrando qualche problemino, vediamo se questa mattina riesco a 
risolvere.
Grazie e ciao... Maurizio 

file
ad una temporanea, e riportarla a quella esatta dopo la conclusione della
scrittura del file.
...
Risolto!
Come scrivevo, ho usato anche la data di creazione del file, impostandola 
all'inizio del processo al 1900, e reimpostandola al valore giusto una volta 
che la copia e' terminata.
Se, nella ripartenza del programma, mi accorgo che sto per copiare un file 
con data di creazione assurda, evito la copia.
Grazie ancora... Maurizio

 wrote:
zac
file "pippo.doc" ORIGINE
1 step) COPIA
leggi tutti i byte in un buffer....calcolati il crc o
l'hash(storicamente il crc)
scrivi il file con un nome convenzionale nella destinazione
"temp00001.dat" ...il crc lo mantieni in memoria o scrivi anche un
"filetemp00001.crc"
2 step) CONTROLLO
leggi il file "temp00001.dat" in un buffer
calcola il crc...confrontalo con l'originale
E' uguale? Rinominalo come vuoi impostando la data che vuoi!
E' diverso? butta via il file temporaneo e scrivi nel log errori
oppure ricomincia la copia!
Sistema semplice di derivazione unix che se correttamente implementato
ti rende pressochè impossibile sbagliare una copia!
Ricordati di calcolare il crc SOLO sul contenuto byte per
byte...altrimenti non ti torna mai uguale!

file "pippo.doc" ORIGINE
1 step) COPIA
leggi tutti i byte in un buffer....calcolati il crc o
l'hash(storicamente il crc)
...
Il problema e' che ho a che fare anche con files molto grandi, sopra il GB. 
Il calcolo di un checksum rallenterebbe molto l'elaborazione.


Il problema è che così facendo NON SAI se la copia è buona!...mentre
con il crc si!

Il problema � che cos� facendo NON SAI se la copia � buona!...mentre
con il crc si!
...
Ho dovuto girare intorno al problema, perche' il tempo di copia era 
veramente troppo alto.
Sono tornato ad utilizzare oggetti di tipo System.IO.FileInfo e il metodo 
CopyTo di questa classe.
Attualmente faccio una copia del file che mi serve verso un file temporaneo, 
se sono arrivato alla fine del processo, e quindi non ci sono stati errori e 
il sistema e' ancora in piedi, rinomino il file temporaneo con il nome 
definitivo.
Anche in questo caso, come dicevi tu, non ho la certezza matematica che il 
file sia identico, ma e' una tolleranza *tollerabile*. Andare a leggere byte 
per byte impegnava troppo tempo, e la cosa non era ben vista.
Naturalmente, ho dovuto togliere l'indicazione della percentuale di 
elaborazione del file, ora dovro' trovare un metodo diverso per capire a che 
punto della copia sono.
Naturalmente , ogni idea in questo  senso e' benvenuta :-)
Ciao... Maurizio

 ...>Il problema che cos facendo NON SAI se la copia buona!...mentre
zac
in realtà non sò cosa vuoi fare ....è difficile dare consigli!
Vuoi farti un sistema di backup?
C'è un mio amico che da anni copia la notte tutti i lavori del suo
studio di architettura su un altro pc di servizio.
Prima usava un mio vecchio programma in vb5/6 per fare le copie
che usava la API SHFILEOPERATION
http://allapi.mentalis.org/apilist/SHFileOperation.shtml
(Ringrazio GbC per avermi insegnato ad usare questa api!)
potresti usare quella come funzione di copia
e per il checksum(se lo desideri ancora...ma è superfluo perchè si
rende conto da se se il file è effettivamente copiato)
http://msdn.microsoft.com/en-us/library/ms680355(VS.85).aspx
Come velocità ci saresti: ti interfacci al kernel e quindi copi alla
stessa velocità di windows!
Altrimenti butta tutto e usa Cobian Backup
http://www.educ.umu.se/~cobian/cobianbackup.htm

Prima usava un mio vecchio programma in vb5/6 per fare le copie
che usava la API SHFILEOPERATION [...]  Come velocità ci saresti: ti 
interfacci al kernel e quindi copi alla
stessa velocità di windows!
...
Si si, conosco questa api, l'ho usata anche io in alcuni progetti VB6. E' 
solo che usare le api in Net, mi piace poco :-)