Jak: dotaz na největší soubor nebo soubory v adresáři stromu (LINQ)
Tento příklad ukazuje pět dotazy týkající se velikost souboru v bajtech:
Jak získat velikost v bajtech největší soubor.
Jak získat velikost v bajtech nejmenší souboru.
Jak lze získat FileInfo objektu největší nebo nejmenší soubor z jedné nebo více složek v zadané kořenové složky.
Jak načíst sekvence například 10 největších souborů.
Jak soubory objednávky do skupin na základě jejich velikost souboru v bajtech, ignoruje soubory, které jsou menší než zadaná velikost.
Příklad
Následující příklad obsahuje pět samostatné dotazy, které ukazují, jak dotaz a skupiny souborů, v závislosti na jejich velikost souboru v bajtech.Tyto příklady založit na některé jiné vlastnosti dotazu můžete snadno změnit FileInfo objektu.
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
class QueryBySize
{
static void Main(string[] args)
{
QueryFilesBySize();
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
private static void QueryFilesBySize()
{
string startFolder = @"c:\program files\Microsoft Visual Studio 9.0\";
// Take a snapshot of the file system.
System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(startFolder);
// This method assumes that the application has discovery permissions
// for all folders under the specified path.
IEnumerable<System.IO.FileInfo> fileList = dir.GetFiles("*.*", System.IO.SearchOption.AllDirectories);
//Return the size of the largest file
long maxSize =
(from file in fileList
let len = GetFileLength(file)
select len)
.Max();
Console.WriteLine("The length of the largest file under {0} is {1}",
startFolder, maxSize);
// Return the FileInfo object for the largest file
// by sorting and selecting from beginning of list
System.IO.FileInfo longestFile =
(from file in fileList
let len = GetFileLength(file)
where len > 0
orderby len descending
select file)
.First();
Console.WriteLine("The largest file under {0} is {1} with a length of {2} bytes",
startFolder, longestFile.FullName, longestFile.Length);
//Return the FileInfo of the smallest file
System.IO.FileInfo smallestFile =
(from file in fileList
let len = GetFileLength(file)
where len > 0
orderby len ascending
select file).First();
Console.WriteLine("The smallest file under {0} is {1} with a length of {2} bytes",
startFolder, smallestFile.FullName, smallestFile.Length);
//Return the FileInfos for the 10 largest files
// queryTenLargest is an IEnumerable<System.IO.FileInfo>
var queryTenLargest =
(from file in fileList
let len = GetFileLength(file)
orderby len descending
select file).Take(10);
Console.WriteLine("The 10 largest files under {0} are:", startFolder);
foreach (var v in queryTenLargest)
{
Console.WriteLine("{0}: {1} bytes", v.FullName, v.Length);
}
// Group the files according to their size, leaving out
// files that are less than 200000 bytes.
var querySizeGroups =
from file in fileList
let len = GetFileLength(file)
where len > 0
group file by (len / 100000) into fileGroup
where fileGroup.Key >= 2
orderby fileGroup.Key descending
select fileGroup;
foreach (var filegroup in querySizeGroups)
{
Console.WriteLine(filegroup.Key.ToString() + "00000");
foreach (var item in filegroup)
{
Console.WriteLine("\t{0}: {1}", item.Name, item.Length);
}
}
}
// This method is used to swallow the possible exception
// that can be raised when accessing the FileInfo.Length property.
// In this particular case, it is safe to swallow the exception.
static long GetFileLength(System.IO.FileInfo fi)
{
long retval;
try
{
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;
}
}
Vrátit, proveďte jeden nebo více FileInfo objekty dotazu nejdříve přezkoumá každé z nich data zdroje a pak je seřadit podle jejich délka vlastnosti.Je potom vrátit jeden jediný nebo sekvenci s největší délkou.Použití First vrátí první prvek v seznamu.Použití Take<TSource> vrátit první n počet prvků.Určete sestupně nejmenší prvky umístit na začátek seznamu.
Volá dotaz zvláštní metody získat velikost souboru v bajtech pro spotřebovat možnou výjimkou, že bude aktivována v případě, kdy byl soubor odstraněn jiným podprocesem v době od FileInfo objekt byl vytvořen při volání GetFiles.I prostřednictvím FileInfo objekt již byl vytvořen, výjimky může dojít, protože FileInfo objektu se pokusí aktualizovat jeho Length vlastnost pomocí aktuální velikost v bajtech při prvním přístupu k vlastnosti.Uložením této operace v bloku try-catch mimo dotaz jsme podle pravidla vyhnout operací v dotazech, které mohou způsobit vedlejší účinky.Obecně velmi pečlivě je třeba spotřebovávat výjimky, zajistit, že aplikace není ponecháno v neznámém stavu.
Probíhá kompilace kódu
Vytvoření Visual Studio projektu, který se zaměřuje .NET Framework verze 3.5.Projekt obsahuje odkaz na System.Core.dll a using směrnice (C#) nebo Imports prohlášení (Visual Basic) pro výchozí obor názvů System.Linq.
Zkopírujte tento kód do projektu.
Stisknutím klávesy F5 sestavit a spustit program.
Stisknutím libovolné klávesy uzavřete okno konzoly.
Robustní programování
Operace dotazu intenzivní nad obsah více typů dokumentů a souborů, zvažte použití Windows Desktop Search motoru.