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?

- 9,590
- 1
- 27
- 46

- 12,136
- 30
- 85
- 134
8 Answers
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);
}

- 442
- 2
- 16

- 49,173
- 15
- 109
- 139
-
From what I understand c# 4.0 should make this much faster and easier ;-) – Dested Mar 10 '10 at 15:55
-
13You can do this in a single line, without the SELECT **var files = new DirectoryInfo(@"C:\").GetFiles().Where(x => (x.Attributes & FileAttributes.Hidden) == 0);** – Adriaan Stander Mar 10 '10 at 16:00
-
5Or even just use the directory class (reduces @astanders solution by 8 characters) var files = Directory.GetFiles( @"c:\").Where(x=>(x.Attributes & FileAttributes.Hidden)==0); – µBio Mar 10 '10 at 16:24
-
@Dested - I'm using C# 4.0, how does that make this faster and easier?? – James Cadd Mar 10 '10 at 16:57
-
5`Directory.GetFiles` returns a string array so your code golf solution doesn't quite work. – Austin Salonen Mar 10 '10 at 17:00
-
Indeed the `Select` is unnecessary. As for the rest, I was trying to show off the other data types in case the OP was unaware of them. – Austin Salonen Mar 10 '10 at 17:03
-
2@AustinSalonen is correct, you can't use the above "code golf" solution with Directory.GetFiles, but you can use THIS nasty piece of code: Directory.GetFiles(@"C:\").Where(x => (new FileInfo(x).Attributes & FileAttributes.Hidden)==0). I'm not saying you SHOULD, but you COULD. – bopapa_1979 Apr 26 '13 at 18:35
-
This solution will not work with option SearchOption.AllDirectories. – TarmoPikaro May 27 '16 at 05:33
// check whether a file is hidden
bool isHidden = ((File.GetAttributes(filePath) & FileAttributes.Hidden) == FileAttributes.Hidden);

- 9,590
- 1
- 27
- 46

- 141
- 1
- 2
-
-
2Simple solutions can be elegant - I like when people show solutions without showing off Linq – Kairan Nov 16 '13 at 01:38
-
1Or equivalently, File.GetAttributes(filePath).HasFlag(FileAttributes.Hidden) if you're willing to take a minor performance loss. – Warty Nov 12 '14 at 23:39
-
For performance this is not an optimal solution. I tried it on a network device and it was sigifically slower than the accepted answer – Vortex852456 Feb 20 '15 at 10:11
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).

- 5,224
- 3
- 20
- 17
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

- 9
- 1
One line Code:
FileInfo[] tmpFiles = tempDir.GetFiles().Where(file =>
(file.Attributes & FileAttributes.Hidden) == 0).ToArray();

- 14,455
- 21
- 138
- 171
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); );

- 25,873
- 13
- 66
- 85
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.

- 4,723
- 2
- 50
- 62
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:
Create bool that returns true when string contains 'Hidden' ----
static bool IsHidden(string p){return p.Contains("Hidden");}
get directory info ----
DirectoryInfo directory = new DirectoryInfo(@"C:\temp");
get file info array from directory ----
FileInfo[] files = directory.GetFiles();
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()));

- 21
- 3
-
1
-
if you (Ctznkane525) have any doubt check this code and reply me it is right or not – Ujjwal Kashyap Jan 30 '18 at 22:28
-
1It's not me checking it. Procedure on the site to explain code when u post it...fyi – Ctznkane525 Jan 30 '18 at 23:08
-