방법: 폴더 집합의 전체 바이트 수 쿼리(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 엔진을 사용해 보십시오.