Search code examples
c#.netlinuxcross-platformfile-type

How to get the Linux file type (regular, durector, symlink, char device, etc) in .NET?


There are 7 different types of files in Linux:

1. - : regular file
2. d : directory
3. c : character device file
4. b : block device file
5. s : local socket file
6. p : named pipe
7. l : symbolic link

A Linux shell way to get the type for a given file or path is via either ls command, or through a specific cheks like in:

if [ -f path/to/file ] then

which will go into an if the body only if the path/to/file is pointing at a regular file (not a directory, not a symlink, etc.

Is there a .NET way of checking the path type in Linux terms? For instance, I want to have a check which will return true only if File.Exists while pointing at a regular file? What about checking for other types.

Even if right now with .NET 5 checking this is impossible, fine for the question to stick around until this is made possible via managed code, without recording to "call bash -> get results -> process output -> wrap into POCO" way.


Solution

  • It's interesting that even a Linux-friendly language like Java doesn't offer a comprehensive solution to do so.

    Fortunately, File.GetAttributes(string) method provides helpful (but still not as complete as question looks for) information.

    var path = "/path/to/file";
    var attributes = File.GetAttributes(path);
    
    if (attributes.HasFlag(FileAttributes.Directory))
        Console.WriteLine("directory");
    else if (attributes.HasFlag(FileAttributes.Normal))
        Console.WriteLine("file");
    else if (attributes.HasFlag(FileAttributes.ReparsePoint))
        Console.WriteLine("link");
    else if (attributes.HasFlag(FileAttributes.System))
        Console.WriteLine("system");
    

    The code above is tested on multiple sample files over WSL2 and works fine. However, I didn't managed to test all sort of files but it seems some attributes like Device or System represents more than one type out of seven Linux file types.