Cara mengkueri file atau file terbesar di pohon direktori (LINQ) (C#)

Contoh ini menunjukkan lima kueri yang terkait dengan ukuran file dalam byte:

  • Cara mengambil ukuran dalam byte dari file terbesar.

  • Cara mengambil ukuran dalam byte dari file terkecil.

  • Cara mengambil file terbesar atau terkecil objek FileInfo dari satu atau lebih folder pada bagian folder root yang ditentukan.

  • Cara mengambil urutan seperti 10 file terbesar.

  • Cara mengurutkan file ke dalam grup berdasarkan ukuran file dalam byte, mengabaikan file yang kurang dari ukuran yang ditentukan.

Contoh

Contoh berikut berisi lima kueri terpisah yang memperlihatkan cara kueri dan mengelompokkan file, bergantung pada ukuran filenya dalam byte. Anda dapat dengan mudah mengubah contoh ini untuk mendasarkan kueri pada beberapa properti lain dari objek FileInfo.

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;  
    }  
  
}  

Untuk mengembalikan satu atau beberapa objek FileInfo lengkap, kueri terlebih dahulu harus memeriksa masing-masing objek di sumber data, lalu mengurutkannya menurut nilai properti Panjangnya. Kemudian dapat mengembalikan satu atau urutan dengan panjang terbesar. Gunakan First untuk mengembalikan elemen pertama dalam daftar. Gunakan Take untuk mengembalikan n jumlah elemen pertama. Tentukan urutan pengurutan menurun untuk menempatkan elemen terkecil di awal daftar.

Kueri memanggil metode terpisah untuk mendapatkan ukuran file dalam byte untuk menggunakan kemungkinan pengecualian yang akan muncul dalam kasus yang filenya dihapus di utas lain dalam periode waktu sejak objek FileInfo dibuat dalam panggilan ke GetFiles. Meskipun objek FileInfo telah dibuat, pengecualian dapat terjadi karena objek FileInfo akan mencoba me-refresh properti Length-nya dengan menggunakan ukuran terbaru dalam byte saat pertama kali properti diakses. Dengan menempatkan operasi ini di blok try-catch di luar kueri, kita mengikuti aturan menghindari operasi dalam kueri yang dapat menyebabkan efek samping. Secara umum, perhatian besar harus diberikan saat menggunakan pengecualian, untuk memastikan bahwa aplikasi tidak dibiarkan dalam status tidak dikenal.

Mengompilasi Kode

Buat proyek aplikasi konsol C#, dengan arahan using untuk namespace layanan System.Linq dan System.IO.