Delucidazioni su oggetti directory e directoryinfo

lunedì 20 febbraio 2012 - 13.27
Tag Elenco Tags  C#  |  Visual Studio 2010

andrestu Profilo | Expert

Salve a tutti,
scrivo questo post perchè ho dei problemi nel gestire la copia di cartelle e file, per farvi un esempio banale ho creato un metodo che elimina una cartella X per poi ricrearla nello stesso percorso e copiarci dentro dei file, questo è lo schema:

- se cartella X esiste la elimino
- ricreo nello stesso percorso la cartella X
- se cartella X esiste copio dei file da cartella Y in cartella X

Alle volte però (non sempre) mi succede che durante questa procedura mi genera un eccezione di accesso negato perchè non trova la cartella di destinazione per la copia eppure nella procedura ci sono tutti i controlli dovuti, e cioè la copia viene eseguita solo se la cartella X esiste. Quando genera l'eccezzione vado a controllare e in effetti la cartella non è stata creata.

esempio:
elimino cartella X
creo cartella X
if(cartella X esiste){
esegui copia
}

la cosa è abbastanza scorcentante, non credete?
- eseguo un metodo per la creazione della cartella e non viene creata
- faccio un controllo su una cartella che non esiste e il sistema la rileva come esistente
I controlli sulle cartelle vengono fatti da metodi statici dell'oggetto Directory e sinceramente a questo punto metto in dubbio la funzionalità di questo oggetto.
Potrebbe essere una problematica di tempistiche? e cioè il sistema in qualche modo inizia l'eliminazione della cartella ma prima che l'eliminazione effettiva viene effettuata il metodo continua a essere processato creando così problemi di sincronizzazione...
Secondo voi ? suggerimenti ? non so che pesci prendere!!!

Andrea Restucci - Web Developer

Gho5t Profilo | Junior Member

Ciao,
visto che il problema sembra essere l'eliminazione e la ricreazione della cartella, perché non aggiri l'ostacolo?
Invece di eliminare la cartella elimina tutti i file all'interno di quella cartella e poi copia i nuovi file al loro posto.
string[] filePaths = System.IO.Directory.GetFiles(@"c:\MyDir\"); foreach (string file in filePaths) { System.IO.File.Delete(file); } //Copio i nuovi file

p.s. Prova il codice che ti ho passato perché l'ho fatto in fretta e non l'ho testato... xd
Se un uomo non è disposto a correre qualche rischio per le sue idee, o le sue idee non valgono nulla o non vale nulla lui

martinez Profilo | Senior Member

>Salve a tutti,
Ciao!

>scrivo questo post perchè ho dei problemi nel gestire la copia
>di cartelle e file, per farvi un esempio banale ho creato un
>metodo che elimina una cartella X per poi ricrearla nello stesso
>percorso e copiarci dentro dei file, questo è lo schema:
>
>- se cartella X esiste la elimino
La prima domanda che ho da porti è se utilizzi la clausola (true) per consentire l'eliminazione di tutti i file e sottocartelle dell'istanza DirectoryInfo, (ad esempio: TuaDir.Delete(True)). Perché altrimenti se la directory da cancellare non fosse vuota l'operazione non verrebbe eseguita ...

>- ricreo nello stesso percorso la cartella X
>- se cartella X esiste copio dei file da cartella Y in cartella
>X
Qui invece farei notare che: se la tua cartella da eliminare contenesse 1.000.000 di file e sottocartelle da occupare per esempio 1GB di spazio disco ... Secondo te si farebbe in tempo ad eliminare tutto prima che l'algoritmo arrivi allo step di (ri)creazione cartella?
A mio parere no ... ed in alcuni casi ho verificato personalmente questa problematica ... ed ho risolto in questo modo:
1) verifico presenza cartella X
2) rinomino la cartella X ... praticamente la sposto ... ( DirectoryInfo.MoveTo("NewTempDir");
3) Ricreo la cartella X;
4) Copio la Dir Y in dir X
5) elimino la vecchia cartella X (NewTempDir)
Questo procedimento non mi ha mai dato alcun problema anche con grosse quantità di dati.

>la cosa è abbastanza scorcentante, non credete?
>- eseguo un metodo per la creazione della cartella e non viene
>creata
>- faccio un controllo su una cartella che non esiste e il sistema
>la rileva come esistente
>I controlli sulle cartelle vengono fatti da metodi statici dell'oggetto
>Directory e sinceramente a questo punto metto in dubbio la funzionalità
>di questo oggetto.
Credo che l'oggetto funzioni abbastanza bene anche se devo ammettere sia un pochino ostico da gestire e capire ma meno di altri se può consolare :)

>Potrebbe essere una problematica di tempistiche? e cioè il sistema
>in qualche modo inizia l'eliminazione della cartella ma prima
>che l'eliminazione effettiva viene effettuata il metodo continua
>a essere processato creando così problemi di sincronizzazione...
>Secondo voi ? suggerimenti ? non so che pesci prendere!!!
SI secondo me è questo il problema appunto ....

Saluti Antonio

andrestu Profilo | Expert

ciao,
grazie per le risposte,
diciamo subito che tutti i controlli del caso vengono fatti, anche perchè altrimenti il problema si presenterebbe regolarmente facendo la stessa operazione sui stessi tipi di cartelle e invece no, il problema si presenta a random sia che le cartella in questione è o non è vuota e poi la cosa che mi lascia un pò perplesso è che mi è capitato che l'eccezione viene generata dal metodo "copia file" pur non esistendo la cartella X !!!

metodo "elimina cartella X"
metodo "crea cartella X"
if(cartella X esiste)
{
metodo "copia file"
}

quindi diciamo che se per qualche motivo la cartella non viene creata non dovrebbe nenache provare a fare la copia!!! e invece il sistema la rileva come esistente e quando prova a copiare non esiste più, questo vuol dire che perforza di cose o è un problema o di riutilizzo degli stessi oggetti in maniera errata oppure di tempistiche.
Ora sto facendo un pò di refactoring per vedere se magari il problema viene generato dallo stesso oggetto riutilizzato in maniera errata. intendo l'oggetto directoryInfo.

e comunque la domanda cruciale è,
se io eseguo:

directory.create("path");
metodo successivo
...

prima di eseguire "metodo successivo" il sistema aspetta che la cartella viene creata e fa una verifica in qualche modo sul completamento dell'operazione oppure no??? apparentemente sembra di no.
perchè altrimenti anche se la cartella ha pochi file basta un leggero rallentamento di scrittura dovuto al carico di lavoro che destabilizza tutto!!! non credete?

x Martinez
grazie per il sugg. ma credo che la tua soluzione anche se efficace mi sembra un pò un modo per aggirare il problema e non per risolverlo.

Andrea Restucci - Web Developer

martinez Profilo | Senior Member

Ciao Andrea,

Il mio metodo è dettato dal problema che NON riesco a stabilire da codice se mi trovo nella fase di cancellazione della directory o nella sua fase successiva di creazione ...

se la cartella da eliminare è di grosse dimensioni è molto probabile che mentre il sistema stia cancellando venga lanciato il comando di creazione nuova cartella che purtroppo trova ancora la vecchia esistente nel filesystem e si limita a non ricrearla e nemmeno ad avvisarti del problema ... Il tuo processo inzia quindi la copia dei file dalla Y alla NUOVA X, ma che in realtà è in fase di eliminazione ed è sempre la stessa vecchia X purtroppo, quindi quando si avvera la cancellazione definitiva della cartella X ecco che la copia dei file va in errore magari nel bel mezzo del ciclo ... perché da questo momento la cartella in realtà non esiste più ... Invece spostando la vecchia in una directory temporanea e creando ad HOC la X il problema precedente non ha modo di esistere ...

Non conosco alternative al problema se risolvi diversamente fammi sapere che sono interessatissimo!

andrestu Profilo | Expert

e si infatti, mi sembra strano che su un problema così sensibile Microsoft non abbia adottato qualche soluzione effiace , basterebbe fare in modo che il thread si pausi in automatico fino al completamento della scrittura/lettura...
comunque se trovo qualcosa di utile lo posto, per ora vado di fretta e anchio cerco di aggirare tramite metodi vari.
ciao a presto

martinez Profilo | Senior Member

Ancora Ciao!

>e si infatti, mi sembra strano che su un problema così sensibile
>Microsoft non abbia adottato qualche soluzione effiace , basterebbe
>fare in modo che il thread si pausi in automatico fino al completamento
>della scrittura/lettura...

In effetti visto che me l'hai detto, ci ho riflettuto ... ed è veramente strano che Mamma Microsft non abbia una soluzione al problema ....
cerca e ricerca ed ecco qui: http://msdn.microsoft.com/it-it/library/system.io.filesystemwatcher(v=vs.100).aspx
dimmi se può fare al caso tuo :) testalo per benino e se ti convince dimmelo che cambio anche i miei metodi futuri (egoismo)!!!
>
>ciao a presto

Antonio

andrestu Profilo | Expert

grazie del sugg. conoscevo gìà questo oggetto e in effetti studiandoci un pò sù si potrebbe sfruttare il meccanismo anche se il processo risulterebbe molto macchinoso.
Per il momento comunque, cambiando il modo di utilizzare gli oggetti sembra non darmi più problemi, forse il comportamento ipotizzato in precedenza non è corretto, nel senso che non credo che sia un problema di tempistiche, è probabile che li processo continui l'esecuzione solo ad operazione su disco terminata...

Andrea Restucci - Web Developer
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2017
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5