public IEnumerable<string> ControlsAvecRecursivite(string strPath) { DirectoryInfo dInfo = new DirectoryInfo(strPath); System.Security.AccessControl.DirectorySecurity secu = dInfo.GetAccessControl(); bool protect1 = secu.AreAuditRulesProtected; bool protect2 = secu.AreAccessRulesProtected; if (!protect1 && !protect2) { foreach (string c in Directory.EnumerateFiles(strPath, "*")) { if(testTypeFileIsGood(c)) { listBox1.Items.Add(c); toolStripStatusLabel1.Text = (Count++).ToString() + "Fichiers trouvés"; Application.DoEvents(); yield return c; } } foreach (string c in Directory.EnumerateDirectories(strPath, "*")) foreach (string child in ControlsAvecRecursivite(c)) { yield return child; } } }
// version "ameliorée" de EnumerateFiles qui ignore les exceptions sur les fichiers/répertoires inaccessibles // et passe aux suivants sans s'arreter ! private static IEnumerable<String> EnumerateAccessableFiles(string path, string file_pattern, SearchOption searchOption) { // Enumerate the files just in the top directory. var files = Directory.EnumerateFiles(path, file_pattern).GetEnumerator(); while (true) { String file = null; try { if (files.MoveNext()) file = files.Current; else break; } catch (UnauthorizedAccessException) { continue; } catch (PathTooLongException) { continue; } yield return file; } if (searchOption == SearchOption.TopDirectoryOnly) yield break; var dirs = Directory.EnumerateDirectories(path, "*").GetEnumerator(); while (true) { String dir = null; try { if (dirs.MoveNext()) dir = dirs.Current; else break; } catch (UnauthorizedAccessException) { continue; } catch (PathTooLongException) { continue; } foreach (var subpath in EnumerateAccessableFiles(dir, file_pattern, searchOption)) yield return subpath; } }
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre questionprivate delegate void Delegate_ThreadData(); void ThreadData() { if (InvokeRequired) { /*permet de modifier les controles d'une autre thread sinon plantage d'accès */ try { Invoke(new Delegate_ThreadData(ThreadData)); } catch { } } else { while(m_RUN) // m_run pour sortir de ta boucle autrement qu'en faisant un .ABORT { System.thread.threading.sleep(200); // <-- pour éviter de prendre trop de temps UC var matchingFiles = EnumerateAccessableFiles(Trepertoire.Text, "*", SearchOption.AllDirectories) .Where(filePath => extensions.Contains(Path.GetExtension(filePath).ToLower())) // ... uniquement les extensions souhaitées .Where(filePath => excludedKeywords.Any(kw => filePath.Contains(kw)) == false) // ... sans les mots clés exclus .Where(filePath => currentList.Contains(filePath) == false) // ... et sans doublon .Select(filePath => new // classes anonyme locale au scope de matchingFiles uniquement { HasNFO = File.Exists(Path.GetDirectoryName(filePath) + "/" + Path.GetFileNameWithoutExtension(filePath) + ".nfo"), FilePath = filePath }); // le pb avec les controles graphiques est qu'il ne peuvent pas etre modifiés en dehors de leur thread graphique dédié. // Depuis une tache de fond il faut donc "poster" une fonction qui sera executée dans le contexte du thread UI de la fenetre. // C'est a cela que serve les methodes BeginInvoke des controles. // a noter la syntaxe "() =>...", c'est une declaration de methode anonyme en ligne (une lambda) var count = 0; foreach (var match in matchingFiles) { count++; dataGridView1.BeginInvoke((Action)(() => dataGridView1.Rows.Add(match.HasNFO, match.FilePath, Path.GetFileName(match.FilePath)))); toolStripStatusLabel1.Text = "Nombres de films : " + dataGridView1.RowCount.ToString(); System.Threading.Thread.Sleep(10); } } } } #endif }
#region function ajout repertoire //Procedure d'ajout de film via une recherche recursive private void Ajoutrep(bool ajout) { if (ajout == true) { //Creation folderbrowser string listedossiersep = Properties.Settings.Default.listedossier; string [] dossierascanne = listedossiersep.Split('*'); foreach (string dossierscanner in dossierascanne) { progressBar1.Visible = true; progressBar1.Style = ProgressBarStyle.Marquee; // Environment.SpecialFolder root = folderDlg.RootFolder; // MessageBox.Show("Attention pendant la recherche la fenetre active du programme peut figer", "Attention", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); //lance la recherche recursive // BPH : vaut-il mieux parcourir l'ensemble des fichiers une fois et tester l'extension // ou parcourir autant de fois les répertoires que d'extensions a traiter ? // a determiner par des tests mais je dirais plutot la première option // (dependante uniquement du nombre de fichiers dans les repertoires qq soit le nb d'extensions a traiter) MessageBox.Show(dossierscanner); // on recupere la liste courante pour ne pas ajouter de doublon var currentList new HashSet<string>(dataGridView1.Rows.OfType<DataGridViewRow>().Select(r> (string)r.Cells[1].Value)); // on declare ici une tache de fond qui fera le recherche en parallele du "thread UI", evitant ainsi de figer l'interface // qui peut continuer de recevoir et traiter les evenements de la fenetre. var task new Task(()> { // On utilisera EnumerateFiles qui renvoie les fichiers un a un alors que GetFiles va tous les rechercher d'abord et les renvoyer en une fois dans un tableau // Avec GetFiles, on ne pourrait pas avoir la liste qui se remplit au fur et a mesure dans la grille // mathingFiles est ce qu'on appelle une requete Linq, je te laisse decouvrir ca sur le net, cela evite notamment beaucoup de boucles foreach ! // BONUS : j'ai remplacé Directory.EnumerateFiles par une methode perso qui ne plante pas qd elle tombe sur un fichier ou repertoire inaccessible ;-) var matchingFiles = EnumerateAccessableFiles(dossierscanner, "*", SearchOption.AllDirectories) .Where(filePath => extensions.Contains(Path.GetExtension(filePath).ToLower())) // ... uniquement les extensions souhaitées .Where(filePath => excludedKeywords.Any(kw => filePath.Contains(kw)) == false) // ... sans les mots clés exclus .Where(filePath => currentList.Contains(filePath) == false) // ... et sans doublon .Select(filePath => new // classes anonyme locale au scope de matchingFiles uniquement { HasNFO = File.Exists(Path.GetDirectoryName(filePath) + "/" + Path.GetFileNameWithoutExtension(filePath) + ".nfo"), FilePath = filePath }); // le pb avec les controles graphiques est qu'il ne peuvent pas etre modifiés en dehors de leur thread graphique dédié. // Depuis une tache de fond il faut donc "poster" une fonction qui sera executée dans le contexte du thread UI de la fenetre. // C'est a cela que serve les methodes BeginInvoke des controles. // a noter la syntaxe "() =>...", c'est une declaration de methode anonyme en ligne (une lambda) var count = 0; foreach (var match in matchingFiles) { count++; dataGridView1.BeginInvoke((Action)(() => dataGridView1.Rows.Add(match.HasNFO, match.FilePath, Path.GetFileName(match.FilePath)))); //toolStripStatusLabel1.Text = "Nombres de films : " + dataGridView1.RowCount.ToString(); System.Threading.Thread.Sleep(100); } return count; }); // une continuation permet d'executer du code qd la tache se termine (correctement ou en erreur ou les deux au choix) task.ContinueWith((t) => { toolStripStatusLabel1.Text = "Nombres de films : " + dataGridView1.RowCount.ToString(); // D'un point de vue ergonomique, il serait preferable de ne pas trier la liste automatiquement a le fin de la recherche // au risque de perdre la selection et la position courante de l'utilisateur. // Le mieux serait d'avoir une grille capable de trier les lignes en cliquant sur les entetes de colonnes et de laisser faire l'utilisateur //dataGridView1.Sort(dataGridView1.Columns[2], ListSortDirection.Ascending); // attention bug : exception si la liste est vide ;-) // de plus, cf remarque ci dessus, pour ne pas perdre la selection courante de l'utilisateur //dataGridView1.CurrentCell = dataGridView1.Rows[0].Cells[2]; // sauvegarde de la liste dans un fichier XML var actualList dataGridView1.Rows.OfType<DataGridViewRow>().Select(r> new { HasNFO = (bool)r.Cells[0].Value, FilePath = (string)r.Cells[1].Value }); var xDoc = new XDocument(new XDeclaration("1.0", "utf-8", "yes"), new XElement("VideoList", actualList.Select(l => new XElement("FilePath", l.FilePath, new XAttribute("HasNFO", l.HasNFO))))); xDoc.Save(xmlListFilePath); progressBar1.Visible = false; progressBar1.Style = ProgressBarStyle.Continuous; if (t.Result != 0) { // MessageBox.Show(String.Format("{0} nouveaux fichiers trouvés", t.Result), "Recherche terminée.", MessageBoxButtons.OK, MessageBoxIcon.Information); } if (t.Result == 0) { // MessageBox.Show(String.Format("Pas de nouveau fichier trouvé"), "Recherche terminée.", MessageBoxButtons.OK, MessageBoxIcon.Information); } }, TaskScheduler.FromCurrentSynchronizationContext()); // ici on demarre rellement l'exécution de la tache ! task.Start(); } }
int Count = 0; int CountAll = 0; bool m_RUN = false; System.Threading.Thread MyThread; //---------------------------------------------------------------------------// private delegate void Delegate_ThreadData(); void ThreadData() { if (InvokeRequired) { /*permet de modifier les controles d'une autre thread sinon plantage d'accès */ try { Invoke(new Delegate_ThreadData(ThreadData)); } catch { } } else { while (m_RUN) // m_run pour sortir de ta boucle autrement qu'en faisant un .ABORT { Count = 0; CountAll = 0; foreach (string strFichier in ChercheFiles("F:\")) { listBox1.Items.Add(strFichier); toolStripStatusLabel1.Text = (Count).ToString() + "Fichiers trouvés"; toolStripStatusLabel2.Text = "sur " + (CountAll).ToString() + " Fichiers au total"; } System.Threading.Thread.Sleep(1000); } } } //---------------------------------------------------------------------------// bool testTypeFileIsGood(string file) { if(Path.GetExtension(file) == ".txt") return true; else return false; } //---------------------------------------------------------------------------// public IEnumerable ChercheFiles(string strPath) { DirectoryInfo dInfo = new DirectoryInfo(strPath); System.Security.AccessControl.DirectorySecurity secu = dInfo.GetAccessControl(); bool protect1 = secu.AreAuditRulesProtected; bool protect2 = secu.AreAccessRulesProtected; if (!protect1 && !protect2) { foreach (string c in Directory.EnumerateFiles(strPath, "*")) { CountAll++; if (testTypeFileIsGood(c)) { Count++; Application.DoEvents(); yield return c; } } foreach (string c in Directory.EnumerateDirectories(strPath, "*")) foreach (string child in ChercheFiles(c)) { yield return child; } } } private void button1_Click(object sender, EventArgs e) { // je lance la thread d'ici, après tu fais ce que tu veux. m_RUN = true; MyThread = new System.Threading.Thread(ThreadData); MyThread.Start(); }
int Count = 0; int CountAll = 0; bool m_RUN = false; System.Threading.Thread MyThread; List<string> ListPath = new List<string>(); //---------------------------------------------------------------------------// private delegate void Delegate_FuncChercheFichier(string strPath); void FuncChercheFichier(string strPath) { if (InvokeRequired) { /*permet de modifier les contrôles d'une autre thread sinon plantage d'accès */ /* Obligation de le dissocier de la Thread principale à cause du parallélisme Net 4.0 */ try { Invoke(new Delegate_FuncChercheFichier(FuncChercheFichier), strPath); } catch { } } else { foreach (string strFichier in ChercheFiles(strPath)) { listBox1.Items.Add(strFichier); toolStripStatusLabel1.Text = (Count).ToString() + " Fichiers trouvés"; } } } void ParallelThreadData() { System.Diagnostics.Stopwatch ST1 = new System.Diagnostics.Stopwatch(); ST1.Start(); while (m_RUN) // m_run pour sortir de ta boucle autrement qu'en faisant un .ABORT { Count = 0; CountAll = 0; Parallel.ForEach(ListPath, Direct => { FuncChercheFichier(Direct); }); /* foreach(string Direct in ListPath) { FuncChercheFichier(Direct); } */ System.Threading.Thread.Sleep(1000); m_RUN = false; // >> UN SEUL TEST !! } ST1.Stop(); MessageBox.Show(ST1.ElapsedMilliseconds.ToString()); // Se déclenche seulement a la fin de "TOUTE" la procédure donc tu connais la fin. } //---------------------------------------------------------------------------// bool testTypeFileIsGood(string file) { if(Path.GetExtension(file) == ".txt") return true; else return false; } //---------------------------------------------------------------------------// public IEnumerable ChercheFiles(string strPath) { DirectoryInfo dInfo = new DirectoryInfo(strPath); System.Security.AccessControl.DirectorySecurity secu = dInfo.GetAccessControl(); bool protect1 = secu.AreAuditRulesProtected; bool protect2 = secu.AreAccessRulesProtected; if (!protect1 && !protect2 && dInfo.Exists /* test complémentaire */ ) { foreach (string c in Directory.EnumerateFiles(strPath, "*")) { CountAll++; Application.DoEvents(); if (testTypeFileIsGood(c)) { Count++; yield return c; } } foreach (string c in Directory.EnumerateDirectories(strPath, "*")) foreach (string dir in ChercheFiles(c)) { yield return dir; } } } private void button1_Click(object sender, EventArgs e) { m_RUN = true; MyThread = new System.Threading.Thread(ParallelThreadData); ListPath.Add("D:\"); ListPath.Add("E:\"); ListPath.Add("F:\"); MyThread.Start(); }
Parallel.ForEach(ListPath, Direct => { FuncChercheFichier(Direct); });
FuncChercheFichier(Direct);
public IEnumerable ChercheFiles(string strPath) { DirectoryInfo dInfo = new DirectoryInfo(strPath); System.Security.AccessControl.DirectorySecurity secu = dInfo.GetAccessControl(); bool protect1 = secu.AreAuditRulesProtected; bool protect2 = secu.AreAccessRulesProtected; if (!protect1 && !protect2/*&& dInfo.Exists*/) { foreach (string c in Directory.EnumerateFiles(strPath, "*")) { CountAll++; if (testTypeFileIsGood(c)) { Count++; yield return c; } } foreach (string c in Directory.EnumerateDirectories(strPath, "*")) foreach (string child in ChercheFiles(c)) { Repertoires++; yield return child; } } }
void ParallelThreadData() { System.Diagnostics.Stopwatch ST1 = new System.Diagnostics.Stopwatch(); ST1.Start(); while (m_RUN) // m_run pour sortir de ta boucle autrement qu'en faisant un .ABORT { Count = 0; CountAll = 0; Repertoires = 0; Parallel.ForEach(ListPath, Direct => { FuncChercheFichier(Direct); }); //System.Threading.Thread.Sleep(1000); m_RUN = false; // >> UN SEUL TEST !! } ST1.Stop(); MessageBox.Show(ST1.ElapsedMilliseconds.ToString()); }
avec ses délégués : // Le code asynchrone backgroundWorker1.DoWork += ... // Fin du process backgroundWorker1.RunWorkerCompleted += ... // Progress backgroundWorker1.ProgressChanged += ... // Et ses propriétés, comme l'annulation par exemple DoWorkEventArgs.Cancel
static void ListDirectoriesAndFiles(FileSystemInfo[] FSInfo, string SearchString) { if (FSInfo == null) throw new ArgumentNullException("FSInfo"); if (SearchString null || SearchString.Length 0) throw new ArgumentNullException("SearchString"); foreach (FileSystemInfo i in FSInfo) { // is DirectoryInfo, Iterate if (i is DirectoryInfo) ListDirectoriesAndFiles(((DirectoryInfo)i).GetFileSystemInfos(SearchString), SearchString); // is FileInfo, fait quelque chose avec le fichier else if (i is FileInfo) DoSomethingWithFile(i); } }
string searchStringDir = "*"; FileSystemInfo[] infos = dir.GetFileSystemInfos(searchStringDir); ListDirectoriesAndFiles(infos, searchStringDir);
while(m_run) { Ajoutrep(bool ajout); }
private delegate void Delegate_FuncChercheFichier(var strPath); void FuncChercheFichier(var strPath) { if (InvokeRequired) { try { Invoke(new Delegate_FuncChercheFichier(FuncChercheFichier), strPath); } catch { } } else { // ACCES A TES CONTROLS }