[C#] C #의 디렉토리에있는 모든 파일을 재귀 적으로 나열하는 방법은 무엇입니까?

C #에서 디렉토리 및 하위 디렉토리의 모든 파일을 재귀 적으로 나열하는 방법은 무엇입니까?



답변

이 기사 는 필요한 모든 것을 다룹니다. 파일 검색 및 이름 비교와 달리 이름을 인쇄하십시오.

다음과 같이 수정할 수 있습니다.

static void DirSearch(string sDir)
{
    try
    {
        foreach (string d in Directory.GetDirectories(sDir))
        {
            foreach (string f in Directory.GetFiles(d))
            {
                Console.WriteLine(f);
            }
            DirSearch(d);
        }
    }
    catch (System.Exception excpt)
    {
        Console.WriteLine(excpt.Message);
    }
}

추가 한 barlop

GONeale은 위의 내용은 현재 디렉토리의 파일을 나열하지 않으며 디렉토리를 가져 오는 부분 외부에 파일 목록 부분을 배치하도록 제안합니다. 다음은 그렇게 할 것입니다. 또한 주석 처리를 취소 할 수있는 Writeline 줄도 포함되어 있습니다.이 줄은 재귀의 현재 위치를 추적하여 재귀 작동 방식을 보여주는 호출을 표시하는 데 도움이 될 수 있습니다.

            DirSearch_ex3("c:\\aaa");
            static void DirSearch_ex3(string sDir)
            {
                //Console.WriteLine("DirSearch..(" + sDir + ")");
                try
                {
                    Console.WriteLine(sDir);

                    foreach (string f in Directory.GetFiles(sDir))
                    {
                        Console.WriteLine(f);
                    }

                    foreach (string d in Directory.GetDirectories(sDir))
                    {
                        DirSearch_ex3(d);
                    }
                }
                catch (System.Exception excpt)
                {
                    Console.WriteLine(excpt.Message);
                }
            }


답변

.NET 4.0에는 배열 기반이 아닌 반복자 기반 파일 기능이 내장되어 있습니다.

foreach (string file in Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories))
{
    Console.WriteLine(file);
}

현재 나는 다음과 같은 것을 사용할 것입니다. 단일 하위 디렉토리에 액세스 할 수 없으면 내장 재귀 메소드가 너무 쉽게 끊어집니다. Queue<string>사용은 너무 많이 호출 스택 재귀를 방지하고, 반복자 블록은 우리가 거대한 배열을 가진 방지 할 수 있습니다.

static void Main() {
    foreach (string file in GetFiles(SOME_PATH)) {
        Console.WriteLine(file);
    }
}

static IEnumerable<string> GetFiles(string path) {
    Queue<string> queue = new Queue<string>();
    queue.Enqueue(path);
    while (queue.Count > 0) {
        path = queue.Dequeue();
        try {
            foreach (string subDir in Directory.GetDirectories(path)) {
                queue.Enqueue(subDir);
            }
        }
        catch(Exception ex) {
            Console.Error.WriteLine(ex);
        }
        string[] files = null;
        try {
            files = Directory.GetFiles(path);
        }
        catch (Exception ex) {
            Console.Error.WriteLine(ex);
        }
        if (files != null) {
            for(int i = 0 ; i < files.Length ; i++) {
                yield return files[i];
            }
        }
    }
}


답변

Directory.GetFiles("C:\\", "*.*", SearchOption.AllDirectories)


답변

.NET 4.5에는 최소한이 버전이 훨씬 짧으며 목록에 포함 할 파일 기준을 평가할 수있는 추가 보너스가 있습니다.

public static IEnumerable<string> GetAllFiles(string path,
                                              Func<FileInfo, bool> checkFile = null)
{
    string mask = Path.GetFileName(path);
    if (string.IsNullOrEmpty(mask)) mask = "*.*";
    path = Path.GetDirectoryName(path);
    string[] files = Directory.GetFiles(path, mask, SearchOption.AllDirectories);

    foreach (string file in files)
    {
        if (checkFile == null || checkFile(new FileInfo(file)))
            yield return file;
    }
}

다음과 같이 사용하십시오.

var list = GetAllFiles(mask, (info) => Path.GetExtension(info.Name) == ".html").ToList();


답변

IEnumerable<string> GetFilesFromDir(string dir) =>
 Directory.EnumerateFiles(dir).Concat(
 Directory.EnumerateDirectories(dir)
          .SelectMany(subdir => GetFilesFromDir(subdir)));


답변

Framework 2.0에서는 다음을 사용할 수 있습니다 (루트 폴더의 파일을 나열합니다. 가장 인기있는 답변입니다).

static void DirSearch(string dir)
{
    try
    {
        foreach (string f in Directory.GetFiles(dir))
            Console.WriteLine(f);
        foreach (string d in Directory.GetDirectories(dir))
        {
            Console.WriteLine(d);
            DirSearch(d);
        }

    }
    catch (System.Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}


답변

훌륭한 답변이지만 이러한 답변으로 내 문제를 해결하지 못했습니다.

폴더 권한 문제가 발생하자마자 “권한이 거부되었습니다”코드가 실패합니다. 이것이 “권한 거부”문제를 해결하는 데 사용한 것입니다.

private int counter = 0;

    private string[] MyDirectories = Directory.GetDirectories("C:\\");

    private void ScanButton_Click(object sender, EventArgs e)
    {
        Thread MonitorSpeech = new Thread(() => ScanFiles());
        MonitorSpeech.Start();
    }

    private void ScanFiles()
    {
        string CurrentDirectory = string.Empty;

        while (counter < MyDirectories.Length)
        {
            try
            {
                GetDirectories();
                CurrentDirectory = MyDirectories[counter++];
            }
            catch
            {
                if (!this.IsDisposed)
                {
                    listBox1.Invoke((MethodInvoker)delegate { listBox1.Items.Add("Access Denied to : " + CurrentDirectory); });
                }
            }
        }
    }

    private void GetDirectories()
    {
        foreach (string directory in MyDirectories)
        {
            GetFiles(directory);
        }
    }

    private void GetFiles(string directory)
    {
        try
        {
            foreach (string file in Directory.GetFiles(directory, "*"))
            {
                listBox1.Invoke((MethodInvoker)delegate { listBox1.Items.Add(file); });
            }
        }
        catch
        {
            listBox1.Invoke((MethodInvoker)delegate { listBox1.Items.Add("Access Denied to : " + directory); });
        }
    }

이것이 다른 사람들을 돕기를 바랍니다.