방법: 디렉터리 및 파일 열거

.NET Framework 버전 4부터는 디렉터리 및 파일 이름의 문자열을 포함하는 열거 가능한 컬렉션을 반환하는 메서드를 사용하여 디렉터리 및 파일을 열거할 수 있습니다. 또한 DirectoryInfo, FileInfo 또는 FileSystemInfo 개체를 포함하는 열거 가능한 컬렉션을 반환하는 메서드도 사용할 수 있습니다. 이전 버전의 .NET Framework에서는 이러한 컬렉션의 배열만 가져올 수 있었습니다. 열거 가능한 컬렉션은 배열보다 나은 성능을 제공합니다.

이러한 메서드를 통해 가져온 열거 가능한 컬렉션은 List<T> 클래스 같은 컬렉션 클래스의 생성자에 IEnumerable<T> 매개 변수를 제공하는 데 사용할 수도 있습니다.

디렉터리 또는 파일의 이름만 가져오려면 Directory 클래스의 열거 메서드를 사용합니다. 이름 외에 디렉터리 또는 파일의 다른 속성을 가져오려면 DirectoryInfoFileSystemInfo 클래스를 사용합니다. 또한 텍스트 파일의 줄도 열거할 수 있습니다.

다음 표에서는 열거 가능한 컬렉션을 반환하는 메서드에 대한 지침을 제공합니다.

열거할 대상

반환되는 열거 가능한 컬렉션

사용할 메서드

디렉터리

디렉터리 이름

Directory.EnumerateDirectories

디렉터리 정보(DirectoryInfo)

DirectoryInfo.EnumerateDirectories

파일

파일 이름

Directory.EnumerateFiles

파일 정보(FileInfo)

DirectoryInfo.EnumerateFiles

파일 시스템 정보

파일 시스템 항목

Directory.EnumerateFileSystemEntries

파일 시스템 정보(FileSystemInfo)

DirectoryInfo.EnumerateFileSystemInfos

텍스트 파일의 줄

텍스트 파일의 줄

File.ReadLines

AllDirectories 옵션을 사용하면 부모 디렉터리의 하위 디렉터리에 있는 모든 파일을 즉시 열거할 수 있지만, 이 경우 무단 액세스 예외(UnauthorizedAccessException)로 인해 열거가 완료되지 않을 수도 있습니다. 이러한 예외가 발생할 것으로 보이면 예외를 catch하고 디렉터리를 먼저 열거한 다음 파일을 열거하여 계속합니다.

Windows XP 또는 그 이전 버전을 실행 중인 경우 열거된 디렉터리 또는 파일 중 하나에 열린 핸들이 남아 있으면 열거를 실행한 후 파일 또는 디렉터리에 대해 실행하는 삭제 작업이 실패할 수 있습니다. 이 문제가 발생할 경우 열린 핸들을 제거하도록 가비지 수집을 유도해야 합니다.

디렉터리 이름을 열거하려면

  • Directory.EnumerateDirectories(String) 메서드를 사용하여 지정된 경로에 있는 최상위 수준 디렉터리의 이름 목록을 가져옵니다.

    Imports System.Collections.Generic
    Imports System.IO
    Imports System.Linq
    
    Module Module1
    
        Sub Main()
            Try
                Dim dirPath As String = "\\archives\2009\reports"
    
                ' LINQ query.
                Dim dirs = From folder In _
                    Directory.EnumerateDirectories(dirPath)
                For Each folder In dirs
                    ' Remove path information from string.
                    Console.WriteLine("{0}", _
                            folder.Substring(folder.LastIndexOf("\") + 1))
                Next
                Console.WriteLine("{0} directories found.", _
                    dirs.Count.ToString())
    
                ' Optionally create a List collection.
                Dim workDirs As List(Of String) = New List(Of String)(dirs)
    
            Catch UAEx As UnauthorizedAccessException
                Console.WriteLine(UAEx.Message)
            Catch PathEx As PathTooLongException
                Console.WriteLine(PathEx.Message)
            End Try
        End Sub
    End Module
    
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    
    class Program
    {
    
        private static void Main(string[] args)
        {
            try
            {
                string dirPath = @"\\archives\2009\reports";
    
                // LINQ query.
                var dirs = from dir in 
                         Directory.EnumerateDirectories(dirPath)
                           select dir;
    
                // Show results.
                foreach (var dir in dirs)
                {
                    // Remove path information from string.
                    Console.WriteLine("{0}", 
                        dir.Substring(dir.LastIndexOf("\\") + 1));
    
                }
                Console.WriteLine("{0} directories found.", 
                    dirs.Count<string>().ToString());
    
                // Optionally create a List collection.
                List<string> workDirs = new List<string>(dirs);
            }
            catch (UnauthorizedAccessException UAEx)
            {
                Console.WriteLine(UAEx.Message);
            }
            catch (PathTooLongException PathEx)
            {
                Console.WriteLine(PathEx.Message);
            }
        }
    }
    

모든 디렉터리의 파일 이름을 열거하려면

  • Directory.EnumerateFiles(String, String, SearchOption) 메서드를 사용해 모든 디렉터리를 검색하여 지정된 경로에서 해당 검색 패턴과 일치하는 파일 이름의 목록을 가져옵니다.

    Imports System.IO
    Imports System.Xml.Linq
    Module Module1
    
        Sub Main()
    
            Try
                Dim files = From chkFile In Directory.EnumerateFiles("c:\", "*.txt", _
                                                     SearchOption.AllDirectories)
                            From line In File.ReadLines(chkFile)
                            Where line.Contains("Microsoft")
                            Select New With {.curFile = chkFile, .curLine = line}
    
                For Each f In files
                    Console.WriteLine("{0}\t{1}", f.curFile, f.curLine)
                Next
                Console.WriteLine("{0} files found.", _
                        files.Count.ToString())
            Catch UAEx As UnauthorizedAccessException
                Console.WriteLine(UAEx.Message)
            Catch PathEx As PathTooLongException
                Console.WriteLine(PathEx.Message)
            End Try
        End Sub
    End Module
    
    using System;
    using System.IO;
    using System.Linq;
    
    class Program
    {
        static void Main(string[] args)
        {
    
            try
            {
                var files = from file in Directory.EnumerateFiles(@"c:\",
                                "*.txt", SearchOption.AllDirectories)
                            from line in File.ReadLines(file)
                            where line.Contains("Microsoft")
                            select new
                            {
                                File = file,
                                Line = line
                            };
    
                foreach (var f in files)
                {
                    Console.WriteLine("{0}\t{1}", f.File, f.Line);
                }
                Console.WriteLine("{0} files found.", 
                    files.Count().ToString());
            }
            catch (UnauthorizedAccessException UAEx)
            {
                Console.WriteLine(UAEx.Message);
            }
            catch (PathTooLongException PathEx)
            {
                Console.WriteLine(PathEx.Message);
            }
        }
    }
    

DirectoryInfo 개체 컬렉션을 열거하려면

  • DirectoryInfo.EnumerateDirectories 메서드를 사용하여 최상위 디렉터리의 컬렉션을 가져옵니다.

    ' Create a DirectoryInfo of the Program Files directory.
    Dim dirPrograms As New DirectoryInfo("c:\program files")
    
    Dim StartOf2009 As New DateTime(2009, 1, 1)
    
    ' LINQ query for all directories created before 2009.
    Dim dirs = From dir In dirPrograms.EnumerateDirectories()
                Where dir.CreationTimeUtc < StartOf2009
    
    ' Show results.
    For Each di As DirectoryInfo In dirs
        Console.WriteLine("{0}", di.Name)
    Next
    
    // Create a DirectoryInfo of the Program Files directory.
    DirectoryInfo dirPrograms = new DirectoryInfo(@"c:\program files");
    
    DateTime StartOf2009 = new DateTime(2009, 01, 01);
    
    // LINQ query for all directories created before 2009.
    var dirs = from dir in dirPrograms.EnumerateDirectories()
                where dir.CreationTimeUtc < StartOf2009
                select new
                {
                    ProgDir = dir,
                };
    // Show results.
    foreach (var di in dirs)
    {
        Console.WriteLine("{0}", di.ProgDir.Name);
    }
    

모든 디렉터리에서 FileInfo 개체 컬렉션을 열거하려면

  • DirectoryInfo.EnumerateFiles 메서드를 사용하여 모든 디렉터리에서 해당 검색 패턴과 일치하는 파일의 컬렉션을 가져옵니다. 이 예제에서는 먼저 최상위 수준 디렉터리를 열거하여 발생 가능한 무단 액세스 예외를 catch한 다음 파일을 열거합니다.

    Imports System
    Imports System.IO
    
    Class Program
        Public Shared Sub Main(ByVal args As String())
            ' Create a DirectoryInfo object of the starting directory.
            Dim diTop As New DirectoryInfo("d:\")
            Try
                ' Enumerate the files just in the top directory.
                For Each fi In diTop.EnumerateFiles()
                    Try
                        ' Display each file over 10 MB;
                        If fi.Length > 10000000 Then
                            Console.WriteLine("{0}" & vbTab & vbTab & "{1}", 
                            fi.FullName, fi.Length.ToString("N0"))
                        End If
                    ' Catch unauthorized access to a file.
                    Catch UnAuthTop As UnauthorizedAccessException
                        Console.WriteLine("{0}", UnAuthTop.Message)
                    End Try
                Next
                ' Enumerate all subdirectories.
                For Each di In diTop.EnumerateDirectories("*")
                    Try
                        ' Enumerate each file in each subdirectory.
                        For Each fi In di.EnumerateFiles("*", 
                                    SearchOption.AllDirectories)
                            Try
                                ' // Display each file over 10 MB;
                                If fi.Length > 10000000 Then
                                    Console.WriteLine("{0}" & vbTab &
                                    vbTab & "{1}", 
                                    fi.FullName, fi.Length.ToString("N0"))
                                End If
                            ' Catch unauthorized access to a file.
                            Catch UnAuthFile As UnauthorizedAccessException
                                Console.WriteLine("UnAuthFile: {0}",
                                                    UnAuthFile.Message)
                            End Try
                        Next
                    ' Catch unauthorized access to a subdirectory.
                    Catch UnAuthSubDir As UnauthorizedAccessException
                        Console.WriteLine("UnAuthSubDir: {0}", 
                                                UnAuthSubDir.Message)
                    End Try
                Next
            ' Catch error in directory path.
            Catch DirNotFound As DirectoryNotFoundException
                Console.WriteLine("{0}", DirNotFound.Message)
            ' Catch unauthorized access to a first tier directory. 
            Catch UnAuthDir As UnauthorizedAccessException
                Console.WriteLine("UnAuthDir: {0}", UnAuthDir.Message)
            ' Catch paths that are too long.
            Catch LongPath As PathTooLongException
                Console.WriteLine("{0}", LongPath.Message)
            End Try
        End Sub
    End Class
    
    using System;
    using System.IO;
    
    class Program
    {
        static void Main(string[] args)
        {
            // Create a DirectoryInfo object of the starting directory.
            DirectoryInfo diTop = new DirectoryInfo(@"d:\");
            try
            {
                // Enumerate the files just in the top directory.
                foreach (var fi in diTop.EnumerateFiles())
                {
                    try
                    {
                        // Display each file over 10 MB;
                        if (fi.Length > 10000000)
                        {
                            Console.WriteLine("{0}\t\t{1}", fi.FullName, 
                                            fi.Length.ToString("N0"));
                        }
                    }
                    // Catch unauthorized access to a file.
                    catch (UnauthorizedAccessException UnAuthTop)
                    {
                        Console.WriteLine("{0}", UnAuthTop.Message);
                    }
                }
                // Enumerate all subdirectories.
                foreach (var di in diTop.EnumerateDirectories("*"))
                {
                    try
                    {
                        // Enumerate each file in each subdirectory.
                        foreach (var fi in di.EnumerateFiles("*",
                                        SearchOption.AllDirectories))
                        {
                            try
                            {
                                // Display each file over 10 MB;
                                if (fi.Length > 10000000)
                                {
                                    Console.WriteLine("{0}\t\t{1}", 
                                      fi.FullName, fi.Length.ToString("N0"));
                                }
                            }
                             // Catch unauthorized access to a file.
                            catch (UnauthorizedAccessException UnAuthFile)
                            {
                                Console.WriteLine("UnAuthFile: {0}", 
                                                UnAuthFile.Message);
                            }
                        }
                    }
                    // Catch unauthorized access to a subdirectory.
                    catch (UnauthorizedAccessException UnAuthSubDir)
                    {
                        Console.WriteLine("UnAuthSubDir: {0}", 
                                                UnAuthSubDir.Message);
                    }
                }
            }
            // Catch error in directory path.
            catch (DirectoryNotFoundException DirNotFound)
            {
                Console.WriteLine("{0}", DirNotFound.Message);
            }
            // Catch unauthorized access to a first tier directory. 
            catch (UnauthorizedAccessException UnAuthDir)
            {
                Console.WriteLine("UnAuthDir: {0}", UnAuthDir.Message);
            }
            // Catch paths that are too long. 
            catch (PathTooLongException LongPath)
            {
                Console.WriteLine("{0}", LongPath.Message);
            }
    
        }
    }
    

열거된 디렉터리 또는 파일에서 열린 핸들을 제거하려면

  1. 열거형 코드를 포함할 사용자 지정 메서드(Visual Basic의 경우 함수)를 만듭니다.

  2. NoInlining 옵션을 사용하여 새 메서드에 MethodImplAttribute 특성을 적용합니다. 예를 들면 다음과 같습니다.

    [MethodImplAttribute(MethodImplOptions.NoInlining)]
    Private void Enumerate()
    
  3. 열거형 코드 다음에 실행할 다음 메서드 호출을 포함합니다.

참고 항목

개념

기본 파일 I/O