SUPPRESSION DE RÉPERTOIRE

sebmafate Messages postés 4936 Date d'inscription lundi 17 février 2003 Statut Membre Dernière intervention 14 février 2014 - 5 août 2008 à 11:41
cs_eldim Messages postés 956 Date d'inscription lundi 30 mai 2005 Statut Membre Dernière intervention 21 août 2014 - 5 août 2008 à 14:56
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/47503-suppression-de-repertoire

cs_eldim Messages postés 956 Date d'inscription lundi 30 mai 2005 Statut Membre Dernière intervention 21 août 2014 1
5 août 2008 à 14:56
bon ba vas-y vire le ce source seb
cs_eldim Messages postés 956 Date d'inscription lundi 30 mai 2005 Statut Membre Dernière intervention 21 août 2014 1
5 août 2008 à 13:58
le but c'était de ne pas s'arrêter sur chaque erreur donc en récursif c'est mieux
ensuite le threading.thread...Sleep je le trouve plus lent que l'api

et puis c'est un truc qui m'avais pris 5mn...
pour le reste c'est pas faux
TeBeCo Messages postés 467 Date d'inscription lundi 24 juin 2002 Statut Membre Dernière intervention 9 mars 2011
5 août 2008 à 13:42
sinon tu fais comme sebmafate te le suggère reduis ton code a la simple necessité c'est a dire ici :

Directory.Delete(R.FullName, true);

et poste le dans les snippets
TeBeCo Messages postés 467 Date d'inscription lundi 24 juin 2002 Statut Membre Dernière intervention 9 mars 2011
5 août 2008 à 13:40
Je peux te proposer un tout petit remplacement dans ton code ?
Remplacer:

private void delDir(System.IO.DirectoryInfo R)
{
try
{
affDir(R.FullName);
foreach (System.IO.DirectoryInfo D in R.GetDirectories())
{
delDir(D);
}
foreach (System.IO.FileInfo F in R.GetFiles())
{
try
{
F.Delete();
}
catch (Exception ex)
{
log(ex.Message, "delDir.Files");
}
}
if (R.GetFiles().Length 0 && R.GetDirectories().Length 0)
R.Delete();
else
log("Répertoire " + R.FullName + " non supprimé", "delDir.Aff");
}
catch (Exception ex)
{
log(ex.Message, "delDir");
}
}

par :
Directory.Delete(R.FullName, true);

A par ce petit remplacement
Je te suggère aussi de remplacer :
catch (Exception ex)
{
log(ex.Message, "delDir");
}

Par une réelle prise en charge des erreurs, là ca vaux pas grand chose l'utilisateur sera comme un crétin devant un message du genre : "et nooooon ca marche pas" super ...
ouvre la page des méthode que tu utilises genre pour : Directory.Delete(R.FullName, true);
Tu vas sur MSDN :
http://msdn.microsoft.com/en-us/library/fxeahc5f.aspx
Et la t'as une liste des exceptions que ca peut retourner et c'est les seuls que ca pourra retourner
Donc faut toutes les gérer, je cite :

Exceptions:
* IOException :
A file with the same name and location specified by path exists.
-or-
The directory specified by path is read-only, or recursive is false and path is not an empty directory.
-or-
The directory is the application's current working directory.

* UnauthorizedAccessException :
The caller does not have the required permission.

* ArgumentException :
path is a zero-length string, contains only white space, or contains one or more invalid characters as defined by InvalidPathChars.

* ArgumentNullException :
path is nullNothingnullptra null reference (Nothing in Visual Basic).

* PathTooLongException :
The specified path, file name, or both exceed the system-defined maximum length. For example, on Windows-based platforms, paths must be less than 248 characters and file names must be less than 260 characters.

* DirectoryNotFoundException :
The specified path does not exist or could not be found.
-or-
The specified path is invalid (for example, it is on an unmapped drive).



que dire d'autre hum je dirais :

[System.Runtime.InteropServices.DllImport("kernel32.dll")]
private static extern void Sleep(int msec);

private void affDir(string sD)
{
this.lblAff.Text = sD;
Sleep(1);
}

Le sleep est à éviter
As tu réellement besoin de faire un sleep ce dont je doute ENORMEMENT pour une suppression de répertoire sur le disque dur perso ca me ferais chié de perdre 1 milliseconde sur chaque fichier du disque dur sur une grosse suppression sur mon disque dur au boulot j'ai 137k fichier ca fait plus de 2 minute de bouffer pour rien.
et pour les petites suppressions un Sleep d’une millisecondes est pour le moins symbolique au niveau de la durée mais sert a rien dans le code …

Si tu choisis de faire du C# et donc du .net il faudrait peut être éviter de faire des appels a du code Unmanaged (c'est-à-dire non .Net) autant que possible, je parle de ton API via cette ligne :
[System.Runtime.InteropServices.DllImport("kernel32.dll")]
private static extern void Sleep(int msec);

A quoi ca sert de redéfinir quelque chose de disons "extra .net" alors que ca existe déjà en .net
Même démarche, ouvrons la doc MSDN et demandons nous a quoi sert la fonction
"Sleep" de Kernel32.dll
ca "endors" le thread courant pour le nombre de millisecondes spécifiées
Demandons nous donc si en .net le thread n'existeraient ils pas ?
System.Threading.Thread
Mince ca existe et y a même une propriété statique :
System.Threading.Thread.CurrentThread
Qui renvois l'instance du thread en cours autant dire qu'on se rapproche du but
Maintenant que j'ai mon thread courant faut l'endormir cherchons dans sa liste de membre, a tiens je trouve un "Sleep" qui demande un délai en millisecondes ...
ca ferais donc la même chose
Ce qui reviendrait à écrire ceci :

soit :
System.Threading.Thread.CurrentThread.Sleep(1);
soit :
//avec dans using
using System.Threading;


//dans le code
Thread.CurrentThread.Sleep(1);
Par contre déjà tu devrais passer le thread en Background via le .IsBackground et proposé un curseur pour la priorité via le .Priority de ta classe Thread


Je pourrais aussi te suggérer de changer complètement ta méthode :
private void log(String Message, string sProc);
en quelque chose de plus structuré en commençant déjà par virer la RichTextBox et mettre une ListView
Créé une classe abstraite qui hériterais de ListViewItem avec les propriétés, et assesseurs correspondants a tes infos ainsi que toute la mécanique de log tel que l'horodatage au hasard
gérer ca dans une liste générique du type de ta classe
Ensuite de créé des classe qui hérite de ta classe abstraite qui pourront par exemple gérer des "simulacres" de priorité, warning etc. ...
Et rendre l'affichage propre grâce à cet héritage
Ex :
* choix d'icone automatique d'affichage
* Tri possible en fonction des chemins
* Tri par date
* Tri par évènements etc. ...
Enfin toute la mécanique qu'on attend d'une UI de manipulation de fichier


Et la grande question aussi ...
Pourquoi afficher a la fois le chemin du répertoire à parcourir a la fois dans une textbox a la ligne :
this.txtDel.Text = FBD.SelectedPath;
Et dans un label a la ligne :
this.lblAff.Text = sD;


Déjà c'est assez hasardeux et "dangereux" pour la simple raison qu'il faut penser "double" dans le sens ou a chaque fois que t'en modifie un faut modifier l'autre pour la correspondance. Cela implique un mécanisme pour le moins inattendu et des oublies possibles
Par exemple si quelqu'un va modifier la textbox durant l'opération ca pourrait être sympathique

Et en plus de ca un contrôle a énormément de mécanisme de sécurité pour éviter par exemple le Cross Threading dessus et donc chaque accès a ce contrôle implique des appelle sécuritaire et autre bout de code autour donc lent
Pourquoi ne pas simplement écrire ce chemin dans une variable de type string, donc a accès rapide et ensuite mettre a jour ta textbox quand tu mets a jour ta variable, supprimé ton label et simplement locké la textbox et le mettre en readonly par exemple le temps de l'opération.
sebmafate Messages postés 4936 Date d'inscription lundi 17 février 2003 Statut Membre Dernière intervention 14 février 2014 37
5 août 2008 à 11:41
Mouaip... je pense que tu aurais pu le laisser sur ton disque.

c'est à peine un snippet.
Rejoignez-nous