Gga
Gga

Reputation: 4421

LINQ - select filename and filesize together from Directory.EnumerateFiles

The following LINQ query gives me all files in the specified directory that meet the where clause, in this case filetype and size.

public static List<string> getFs(string sDir)
{

    var files = Directory.EnumerateFiles(sDir, "*.*", SearchOption.AllDirectories)
        .Where(
            s => ((s.ToLower().EndsWith(".ai")) ||
                  (s.ToLower().EndsWith(".psd") && new FileInfo(s).Length > 10000000) ||
                  (s.ToLower().EndsWith(".pdf") && new FileInfo(s).Length > 10000000)
                 ) 
               )
       .Select(
                 s => s.Replace(sDir, "")
               );   

    return files.ToList();
}

At present the file name is returned. I'd like to have the query return both the file name and file size and was wondering how I would incorporate that into the select part?

I am unsure how to select multiple fields in a LINQ query and would be grateful for any pointers.

Thanks.

Upvotes: 0

Views: 2846

Answers (3)

Moha Dehghan
Moha Dehghan

Reputation: 18472

Instead of using Directory.EnumerateFiles and creating a FileInfo, you can use DirectoryInfo class:

var files = new DirectoryInfo(sDir).GetFiles("*.*", SearchOption.AllDirectories)
    .Where(
        s => ((s.FullName.ToLower().EndsWith(".ai")) ||
                (s.FullName.ToLower().EndsWith(".psd") && s.Length > 10000000) ||
                (s.FullName.ToLower().EndsWith(".pdf") && s.Length > 10000000)
                )
            )
    .Select(
                s => new { FileName = s.FullName.Replace(sDir, ""), Length = s.Length }
            );

In this way you have what you want, but you cannot return the result form a function, because a method's return type cannot be an anonymous type. You can create a custom class, or you can use the new Tuple class:

public static List<Tuple<string, long>> getFs(string sDir)
{
    var files = new DirectoryInfo(sDir).GetFiles("*.*", SearchOption.AllDirectories)
        .Where(
            s => ((s.FullName.ToLower().EndsWith(".ai")) ||
                    (s.FullName.ToLower().EndsWith(".psd") && s.Length > 10000000) ||
                    (s.FullName.ToLower().EndsWith(".pdf") && s.Length > 10000000)
                    )
                )
        .Select(
                    s => new Tuple<string, long>(s.FullName.Replace(sDir, ""), s.Length)
                );

    return files.ToList();
}

Usage of the method is like this:

foreach( var t in getFs(@"C:\\Windows\") )
{
    Console.WriteLine( "File name: {0}, File size: {1}", t.Item1, t.Item2 );
}

Upvotes: 2

Angelo Badellino
Angelo Badellino

Reputation: 2201

You can use anonymous type:

public static List<string> getFs(string sDir)
{

    var files = Directory.EnumerateFiles(sDir, "*.*", SearchOption.AllDirectories)
        .Where(
            s => ((s.ToLower().EndsWith(".ai")) ||
                  (s.ToLower().EndsWith(".psd") && new FileInfo(s).Length > 10000000) ||
                  (s.ToLower().EndsWith(".pdf") && new FileInfo(s).Length > 10000000)
                 ) 
               )
       .Select(
                 s => new { s.Replace(sDir, ""), s.Lenght}
               );   

    return files.ToList();
}

Upvotes: 1

kjn
kjn

Reputation: 513

use an anonymous type:

Something like this:

.Select(s => new 
{ 
    fileName = s.Replace(sDir, ""), 
    size = new FileInfo(s).Length 
} );

Upvotes: 1

Related Questions