如何:查詢目錄樹狀中的最大檔案 (LINQ) (Visual Basic)
此範例顯示五個與檔案位元組大小相關的查詢:
如何擷取最大檔案的位元組大小。
如何擷取最小檔案的位元組大小。
如何從所指定根資料夾下的一或多個資料夾中,擷取最大或最小檔案的 FileInfo 物件。
如何擷取序列,例如 10 個最大檔案。
如何根據檔案位元組大小將檔案分組排序,並略過小於指定大小的檔案。
範例
下列範例包含五個不同的查詢,以示範如何根據檔案位元組大小來查詢和分組檔案。 您可以輕鬆修改這些範例,使查詢根據 FileInfo 物件的其他某個屬性。
Module QueryBySize
Sub Main()
' Change the drive\path if necessary
Dim root As String = "C:\Program Files\Microsoft Visual Studio 9.0"
'Take a snapshot of the folder contents
Dim dir As New System.IO.DirectoryInfo(root)
Dim fileList = dir.GetFiles("*.*", System.IO.SearchOption.AllDirectories)
' Return the size of the largest file
Dim maxSize = Aggregate aFile In fileList Into Max(GetFileLength(aFile))
'Dim maxSize = fileLengths.Max
Console.WriteLine("The length of the largest file under {0} is {1}", _
root, maxSize)
' Return the FileInfo object of the largest file
' by sorting and selecting from the beginning of the list
Dim filesByLengDesc = From file In fileList _
Let filelength = GetFileLength(file) _
Where filelength > 0 _
Order By filelength Descending _
Select file
Dim longestFile = filesByLengDesc.First
Console.WriteLine("The largest file under {0} is {1} with a length of {2} bytes", _
root, longestFile.FullName, longestFile.Length)
Dim smallestFile = filesByLengDesc.Last
Console.WriteLine("The smallest file under {0} is {1} with a length of {2} bytes", _
root, smallestFile.FullName, smallestFile.Length)
' Return the FileInfos for the 10 largest files
' Based on a previous query, but nothing is executed
' until the For Each statement below.
Dim tenLargest = From file In filesByLengDesc Take 10
Console.WriteLine("The 10 largest files under {0} are:", root)
For Each fi As System.IO.FileInfo In tenLargest
Console.WriteLine("{0}: {1} bytes", fi.FullName, fi.Length)
Next
' Group files according to their size,
' leaving out the ones under 200K
Dim sizeGroups = From file As System.IO.FileInfo In fileList _
Where file.Length > 0 _
Let groupLength = file.Length / 100000 _
Group file By groupLength Into fileGroup = Group _
Where groupLength >= 2 _
Order By groupLength Descending
For Each group In sizeGroups
Console.WriteLine(group.groupLength + "00000")
For Each item As System.IO.FileInfo In group.fileGroup
Console.WriteLine(" {0}: {1}", item.Name, item.Length)
Next
Next
' 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.
' In this particular case, it is safe to ignore the exception.
Function GetFileLength(ByVal fi As System.IO.FileInfo) As Long
Dim retval As Long
Try
retval = fi.Length
Catch ex As FileNotFoundException
' If a file is no longer present,
' just return zero bytes.
retval = 0
End Try
Return retval
End Function
End Module
若要傳回一或多個完整的 FileInfo 物件,查詢必須先檢查資料來源中的每個物件,再根據其 Length 屬性值進行排序。 然後,它會傳回具有最大長度的單一物件或物件序列。 使用 First 可傳回清單中的第一個項目。 使用 Take 則傳回前 n 個項目。 指定遞減排序次序,則會將最小的項目放在清單的開頭。
查詢會呼叫外面另一個取得檔案位元組大小的方法,以解決可能會因下列狀況引發的例外狀況:自呼叫 GetFiles
而建立 FileInfo 物件以來的這段期間,有另一個執行緒刪除了檔案。 即使已建立 FileInfo 物件,還是可能會發生這個例外狀況,原因是 FileInfo 物件會在它的 Length 屬性第一次受到存取時,嘗試使用目前最新的位元組大小來重新整理這個屬性。 讓這個作業進入查詢外部的 try-catch 區塊,就會遵循規則,以避免查詢中會造成副作業的作業。 一般而言,處理例外狀況時需要十分小心,以確定應用程式不是處於未知狀態。
編譯程式碼
建立 Visual Basic 主控台應用程式專案,其中包含 System.Linq 命名空間的 Imports
陳述式。