C# - Get a list of files excluding those that are hidden
C#.NetFileC# 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:
-
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()));