2012-03-22 17 views
28

Mam następujący kod do rekurencyjnego wyszukiwania plików za pośrednictwem katalogu, który zwraca listę wszystkich plików xml do mnie. Wszystko działa dobrze, z tym wyjątkiem, że pliki xml w katalogu głównym nie znajdują się na liście.Wyszukiwanie pliku w katalogach rekursywnie

Rozumiem, dlaczego, ponieważ pierwszą rzeczą, którą robi, jest pobranie katalogów w katalogu głównym, a następnie pobranie plików, przez co brakuje wywołania GetFiles() w katalogu głównym. Próbowałem, włączając wywołanie GetFiles() przed foreach, ale wyniki nie są takie, jak się spodziewam.

public static ArrayList DirSearch(string sDir) 
{ 
    try 
    { 
     foreach (string d in Directory.GetDirectories(sDir)) 
     { 
      foreach (string f in Directory.GetFiles(d, "*.xml")) 
      { 
       string extension = Path.GetExtension(f); 
       if (extension != null && (extension.Equals(".xml"))) 
       { 
       fileList.Add(f); 
       } 
      } 
      DirSearch(d); 
     } 
    } 
    catch (Exception ex) 
    { 
     Console.WriteLine(ex.Message); 
    } 
    return fileList; 
} 

Moja struktura katalogów jest coś takiego:

RootDirectory 
     test1.0.xml 
      test1.1.xml 
      test1.2.xml 
    2ndLevDir 
      test2.0.xml 
      test2.1.xml 
    3rdLevDir 
       test3.0.xml 
       test3.1.xml 

powraca Kod:

test2.0.xml 
test2.1.xml 
test3.0.xml 
test3.1.xml 

Chciałbym powrócić każdy plik w tym:

test1.0.xml 
test1.1.xml 
test1.2.xml 

Niezbyt dobrze werset z rekursami na. Wszelkie wskazówki byłyby bardzo mile widziane.

+4

'Directory.EnumerateFiles (SDIR "* xml" SearchOption.AllDirectories)' –

Odpowiedz

67

Możesz użyć this overload of Directory.GetFiles, który przeszukuje podfoldery.

+18

'var fileList = Nowe DirectoryInfo (SDIR) .GetFiles (, SearchOption.AllDirectories "* XML.");' –

+1

Czy mogę wprowadzić wiele wzorców wyszukiwania? * Typy plików .xml plus * .doc na przykład ... – Paul

+1

Nie jestem w stanie stwierdzić, ale odpowiednia struktura katalogów prawdopodobnie zostanie zbuforowana po pierwszym wyszukiwaniu. Twoje testy będą w stanie sprawdzić, czy prędkość jest problemem. –

3

Powinieneś mieć pętlę nad plikami przed lub po pętli nad katalogami, ale nie zagnieżdżać się w niej tak, jak to robiłeś.

foreach (string f in Directory.GetFiles(d, "*.xml")) 
{ 
    string extension = Path.GetExtension(f); 
    if (extension != null && (extension.Equals(".xml"))) 
    { 
     fileList.Add(f); 
    } 
} 

foreach (string d in Directory.GetDirectories(sDir)) 
{ 
    DirSearch(d); 
} 
3

Spróbuj następującą metodę:

public static IEnumerable<string> GetXMLFiles(string directory) 
{ 
    List<string> files = new List<string>(); 

    try 
    { 
     files.AddRange(Directory.GetFiles(directory, "*.xml", SearchOption.AllDirectories)); 
    } 
    catch (Exception ex) 
    { 
     Console.WriteLine(ex.Message); 
    } 

    return files; 
} 
1

będziesz wagowo mrówka, aby przenieść pętlę plików poza pętlę dla folderów. Ponadto będziesz musiał przekazać strukturę danych przechowującą zbiór plików do każdego wywołania metody. W ten sposób wszystkie pliki zostaną umieszczone na jednej liście.

public static List<string> DirSearch(string sDir, List<string> files) 
{ 
    foreach (string f in Directory.GetFiles(sDir, "*.xml")) 
    { 
    string extension = Path.GetExtension(f); 
    if (extension != null && (extension.Equals(".xml"))) 
    { 
     files.Add(f); 
    } 
    } 
    foreach (string d in Directory.GetDirectories(sDir)) 
    { 
    DirSearch(d, files); 
    } 
    return files; 
} 

Następnie nazwij to tak.

List<string> files = DirSearch("c:\foo", new List<string>()); 

Aktualizacja:

Dobrze wiemy o mnie, dopóki nie przeczytałem inną odpowiedź w każdym razie, nie jest już wbudowany mechanizm ten sposób. Zostawię odpowiedź na wypadek, gdyby chciał Pan zobaczyć, jak należy zmodyfikować kod, aby działał.

+0

Nie działa. 'f' nie jest zdefiniowane. – Bernard

+0

@Bernard: Naprawiono błąd kopiowania i wklejania ... Dzięki. –

3

Tworzysz trzy listy zamiast jednej (nie używasz wartości zwracanej DirSearch(d)).Można użyć listy jako parametr zapisać stan:

static void Main(string[] args) 
{ 
    var list = new List<string>(); 
    DirSearch(list, "."); 

    foreach (var file in list) 
    { 
    Console.WriteLine(file); 
    } 
} 

public static void DirSearch(List<string> files, string startDirectory) 
{ 
    try 
    { 
    foreach (string file in Directory.GetFiles(startDirectory, "*.*")) 
    { 
     string extension = Path.GetExtension(file); 

     if (extension != null) 
     { 
     files.Add(file); 
     } 
    } 

    foreach (string directory in Directory.GetDirectories(startDirectory)) 
    { 
     DirSearch(files, directory); 
    } 
    } 
    catch (System.Exception e) 
    { 
    Console.WriteLine(e.Message); 
    } 
} 
2

można zrobić coś takiego:

foreach (var file in Directory.GetFiles(MyFolder, "*.xml", SearchOption.AllDirectories)) 
     { 
      // do something with this file 
     } 
0

Korzystanie EnumerateFiles dostać pliki w zagnieżdżonych katalogów. Użyj AllDirectories, aby rekurencyjnie przeglądać katalogi.

using System; 
using System.IO; 

class Program 
{ 
    static void Main() 
    { 
    // Call EnumerateFiles in a foreach-loop. 
    foreach (string file in Directory.EnumerateFiles(@"c:\files", 
     "*.xml", 
     SearchOption.AllDirectories)) 
    { 
     // Display file path. 
     Console.WriteLine(file); 
    } 
    } 
} 
Powiązane problemy