다음을 통해 공유


방법: 폴더 집합의 전체 바이트 수 쿼리(LINQ)

이 예제에서는 지정한 폴더 및 모든 해당 하위 폴더의 모든 파일에서 사용된 총 바이트 수를 검색하는 방법을 보여 줍니다.

예제

Sum 메서드는 select 절에서 선택된 모든 항목의 값을 추가합니다. 이 쿼리를 간단하게 수정할 수 있고 Sum 대신 Min 또는 Max 메서드를 호출하여 지정한 디렉터리 트리에서 가장 큰 파일이나 가장 작은 파일을 검색할 수 있습니다.

Module QueryTotalBytes
    Sub Main()

        ' Change the drive\path if necessary.
        Dim root As String = "C:\Program Files\Microsoft Visual Studio 9.0\VB"

        'Take a snapshot of the folder contents.
        ' This method assumes that the application has discovery permissions
        ' for all folders under the specified path.
        Dim fileList = My.Computer.FileSystem.GetFiles _
                  (root, FileIO.SearchOption.SearchAllSubDirectories, "*.*")

        Dim fileQuery = From file In fileList _
                        Select GetFileLength(file)

        ' Force execution and cache the results to avoid multiple trips to the file system.
        Dim fileLengths = fileQuery.ToArray()

        ' Find the largest file
        Dim maxSize = Aggregate aFile In fileLengths Into Max()

        ' Find the total number of bytes
        Dim totalBytes = Aggregate aFile In fileLengths Into Sum()

        Console.WriteLine("The largest file is " & maxSize & " bytes")
        Console.WriteLine("There are " & totalBytes & " total bytes in " & _
                          fileList.Count & " files under " & root)

        ' Keep the console window open in debug mode
        Console.WriteLine("Press any key to exit.")
        Console.ReadKey()
    End Sub

    ' This method is used to catch the possible exception
    ' that can be raised when accessing the FileInfo.Length property.
    Function GetFileLength(ByVal filename As String) As Long
        Dim retval As Long
        Try
            Dim fi As New System.IO.FileInfo(filename)
            retval = fi.Length
        Catch ex As System.IO.FileNotFoundException
            ' If a file is no longer present,
            ' just return zero bytes. 
            retval = 0
        End Try

        Return retval
    End Function
End Module
class QuerySize
{
    public static void Main()
    {
        string startFolder = @"c:\program files\Microsoft Visual Studio 9.0\VC#";

        // Take a snapshot of the file system.
        // This method assumes that the application has discovery permissions
        // for all folders under the specified path.
        IEnumerable<string> fileList = System.IO.Directory.GetFiles(startFolder, "*.*", System.IO.SearchOption.AllDirectories);

        var fileQuery = from file in fileList
                        select GetFileLength(file);

        // Cache the results to avoid multiple trips to the file system.
        long[] fileLengths = fileQuery.ToArray();

        // Return the size of the largest file
        long largestFile = fileLengths.Max();

        // Return the total number of bytes in all the files under the specified folder.
        long totalBytes = fileLengths.Sum();

        Console.WriteLine("There are {0} bytes in {1} files under {2}",
            totalBytes, fileList.Count(), startFolder);
        Console.WriteLine("The largest files is {0} bytes.", largestFile);

        // Keep the console window open in debug mode.
        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();
    }

    // This method is used to swallow the possible exception
    // that can be raised when accessing the System.IO.FileInfo.Length property.
    static long GetFileLength(string filename)
    {
        long retval;
        try
        {
            System.IO.FileInfo fi = new System.IO.FileInfo(filename);
            retval = fi.Length;
        }
        catch (System.IO.FileNotFoundException)
        {
            // If a file is no longer present,
            // just add zero bytes to the total.
            retval = 0;
        }
        return retval;
    }
}

지정한 디렉터리 트리에서 바이트 수만 계산해야 하는 경우 목록 컬렉션을 데이터 소스로 만드는 오버헤드가 발생하는 LINQ 쿼리를 만들지 않고 이를 좀 더 효율적으로 수행할 수 있습니다. 쿼리가 좀 더 복잡해지거나 같은 데이터 소스에 대해 여러 쿼리를 실행해야 하는 경우 LINQ 방식의 유용성이 더 효율적입니다.

쿼리는 별도의 메서드를 호출하여 파일 길이를 얻습니다. GetFiles에 대한 호출에서 FileInfo 개체가 생성된 이후 다른 스레드에서 파일이 삭제된 경우 발생할 예외를 사용하기 위해 이 작업을 수행합니다. FileInfo 개체가 이미 생성되었더라도 처음 Length 속성에 액세스할 때의 최신 길이를 사용하여 FileInfo 개체가 해당 속성을 새로 고치려고 하기 때문에 예외가 발생할 수 있습니다. 쿼리 외부에 있는 try-catch 블록에 이 작업을 배치하여 코드는 예기치 않은 결과를 일으킬 수 있는 쿼리에서는 작업 방지 규칙을 따릅니다. 일반적으로 예외를 사용할 경우에는 응용 프로그램이 알려지지 않은 상태가 되지 않도록 많은 주의를 기울여야 합니다.

코드 컴파일

  • .NET Framework 버전 3.5를 대상으로 하는 Visual Studio 프로젝트를 만듭니다. 기본적으로 프로젝트에는 System.Core.dll에 대한 참조 및 System.Linq 네임스페이스에 대한 using 지시문(C#) 또는 Imports 문(Visual Basic)이 있습니다. C# 프로젝트에서는 System.IO 네임스페이스에 대한 using 지시문을 추가합니다.

  • 프로젝트에 이 코드를 복사합니다.

  • F5 키를 눌러 프로그램을 컴파일하고 실행합니다.

  • 아무 키나 눌러 콘솔 창을 닫습니다.

강력한 프로그래밍

여러 형식의 문서와 파일의 콘텐츠에서 많이 수행되는 쿼리 작업의 경우 Windows Desktop Search 엔진을 사용해 보십시오.

참고 항목

개념

LINQ to Objects

LINQ 및 파일 디렉터리