C# - Get a list of files excluding those that are hidden

C#.NetFile

C# Problem Overview


Directory.GetFiles() returns all files, even those that are marked as hidden. Is there a way to get a list of files that excludes hidden files?

C# Solutions


Solution 1 - C#

This should work for you:

DirectoryInfo directory = new DirectoryInfo(@"C:\temp");
FileInfo[] files = directory.GetFiles();

var filtered = files.Where(f => !f.Attributes.HasFlag(FileAttributes.Hidden));

foreach (var f in filtered)
{
    Debug.WriteLine(f);
}

Solution 2 - C#

// check whether a file is hidden
bool isHidden = ((File.GetAttributes(filePath) & FileAttributes.Hidden) == FileAttributes.Hidden);

Solution 3 - C#

Using .NET 4.0 and Directory.EnumerateDirectories, you could use this construct :

var hiddenFilesQuery = from file in Directory.EnumerateDirectories(@"c:\temp")
                       let info = new FileInfo(file)
                       where (info.Attributes & FileAttributes.Hidden) == 0
                       select file;

This is basically the same as the other answer, except Directory.EnumerateDirectories is a bit more lazy. This is not very useful if you enumerate everything, though.

(The let is here to have the query a but more readeable).

Solution 4 - C#

if use use:

var filtered = files.Select(f => f) .Where(f => (f.Attributes & FileAttributes.Hidden) == 0);

this only find no hidden file, so you can use :

var filtered = files.Select(f => f) .Where(f => (f.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden);

this is only to read the hidden file

Solution 5 - C#

One line Code:

FileInfo[] tmpFiles = tempDir.GetFiles().Where(file => 
            (file.Attributes & FileAttributes.Hidden) == 0).ToArray();

Solution 6 - C#

I actually rather like passing a function parameter to a method which does what I want it to. I have a SearchDirectory method, which forms the basis for most of the calls I use:

private void SearchDirectory(DirectoryInfo startDirectory, 
                             string pattern, 
                             Action<FileInfo> act)
{
    foreach (var file in startDirectory.GetFiles(pattern))
        act(file);

    foreach (var directory in startDirectory.GetDirectories())
        SearchDirectory(directory, pattern, act);
}

private List<FileInfo> SearchDirectory(DirectoryInfo startDirectory, 
                                       string pattern, 
                                       Func<FileInfo, bool> isWanted)
{
    var lst = new List<FileInfo>();
    SearchDirectory(startDirectory, 
                    pattern, 
                    (fi) => { if (isWanted(fi)) lst.Add(fi); });
    return lst;
}

Then you can use the other solutions listed to write an IsHidden function which takes a single FileInfo, and returns true if so:

private bool IsHiddenDirectory(DirectoryInfo d) {
    if (d == null) return false;
    if (d.Attributes.HasFlag(FileAttributes.Hidden))) return true;
    if (d.Parent == null) return false;
    return IsHiddenDirectory(d.Parent);
}

private bool IsHidden(FileInfo fi) {
    if ((fi.Attributes & FileAttributes.Hidden) != 0) return true;
    // If you're worried about parent directories hidden:
    return IsHiddenDirectory(fi.Directory);
    // otherwise:
    return false;
}

Then I can call it in another method pretty easily:

var files = SearchDirectory(new DirectoryInfo("C:\temp\"),
                            "*.xml",
                            (fi) => { return !IsHidden(fi); );

Solution 7 - C#

If you're using SearchOption.TopDirectoryOnly - then it's relatively simple, however - it gets much more complex if you want to list all files recursively using SearchOption.AllDirectories. If can you GetFiles and then filter out read only, but unfortunately it will not work with directories marked as hidden. Files under that folders gets listed as well, but they are not hidden unlike directory.

You can use also GetDirectories, but again - you cannot list everything recursively using SearchOption.AllDirectories, since it also lists folders which resides under hidden folder, but those folders do not have hidden attribute enabled.

This is the case at least for Tortoise svn .svn hidden folder. It contains a lot of folders which are not hidden, but .svn is hidden. Finally I've wrote function which looks like this:

    SearchOption sopt = SearchOption.AllDirectories;
    List<String> listFiles = new List<string>();
    List<DirectoryInfo> dirs2scan = new List<DirectoryInfo>();

    dirs2scan.Add(new DirectoryInfo(fromPath) );

    for( ; dirs2scan.Count != 0; )
    {
        int scanIndex = dirs2scan.Count - 1;        // Try to preserve somehow alphabetic order which GetFiles returns 
                                                    // by scanning though last directory.
        FileInfo[] filesInfo = dirs2scan[scanIndex].GetFiles(pattern, SearchOption.TopDirectoryOnly);

        foreach (FileInfo fi in filesInfo)
        {
            if (bNoHidden && fi.Attributes.HasFlag(FileAttributes.Hidden))
                continue;

            listFiles.Add(fi.FullName);
        }

        if( sopt != SearchOption.AllDirectories )
            break;

        foreach (DirectoryInfo dir in dirs2scan[scanIndex].GetDirectories("*", SearchOption.TopDirectoryOnly))
        {
            if (bNoHidden && dir.Attributes.HasFlag(FileAttributes.Hidden))
                continue;
                    
            dirs2scan.Add(dir);
        }
        dirs2scan.RemoveAt(scanIndex);
    }

sopt can be used a parameter in function if necessary or removed if not needed.

Solution 8 - C#

static bool IsHidden(string p)
{
 return p.Contains("Hidden");
}

DirectoryInfo directory = new DirectoryInfo(@"C:\temp");
FileInfo[] files = directory.GetFiles();

var filtered = files.Where(f => !IsHidden(File.GetAttributes(f).ToString()));

foreach (var f in filtered)
{
 Debug.WriteLine(f);
}

Steps:

  1. Create bool that returns true when string contains 'Hidden' ---- static bool IsHidden(string p){return p.Contains("Hidden");}

  2. get directory info ---- DirectoryInfo directory = new DirectoryInfo(@"C:\temp");

  3. get file info array from directory ---- FileInfo[] files = directory.GetFiles();

  4. get file info Attributes and convert into string from file info array and check it contains 'Hidden' or not ---- var filtered = files.Where(f=>!IsHidden(File.GetAttributes(f).ToString()));

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJames CaddView Question on Stackoverflow
Solution 1 - C#Austin SalonenView Answer on Stackoverflow
Solution 2 - C#Feedback_looperView Answer on Stackoverflow
Solution 3 - C#Jérôme LabanView Answer on Stackoverflow
Solution 4 - C#jesus gilbertView Answer on Stackoverflow
Solution 5 - C#Alex JoligView Answer on Stackoverflow
Solution 6 - C#JonathanView Answer on Stackoverflow
Solution 7 - C#TarmoPikaroView Answer on Stackoverflow
Solution 8 - C#Ujjwal KashyapView Answer on Stackoverflow