C# - получить список файлов, за исключением тех, которые скрыты
Directory.GetFiles()
возвращает все файлы, даже те, которые помечены как скрытые. Есть ли способ получить список файлов, что исключает скрытые файлы?
8 ответов:
Это должно работать для вас:
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); }
// check whether a file is hidden bool isHidden = ((File.GetAttributes(filePath) & FileAttributes.Hidden) == FileAttributes.Hidden);
использование .NET 4.0 и каталога.EnumerateDirectories, вы можете использовать эту конструкцию:
var hiddenFilesQuery = from file in Directory.EnumerateDirectories(@"c:\temp") let info = new FileInfo(file) where (info.Attributes & FileAttributes.Hidden) == 0 select file;
это в основном то же самое, что и другой ответ, за исключением каталога.EnumerateDirectories немного ленивее. Однако это не очень полезно, если вы перечисляете все.
(пусть здесь есть запрос a, но более читаемый).
если использовать:
var filtered = files.Select(f => f) .Where(f => (f.Attributes & FileAttributes.Hidden) == 0);
это только найти скрытый файл, так что вы можете использовать :
var filtered = files.Select(f => f) .Where(f => (f.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden);
это только для чтения скрытый файл
код одной строки:
FileInfo[] tmpFiles = tempDir.GetFiles().Where(file => (file.Attributes & FileAttributes.Hidden) == 0).ToArray();
Если вы используете SearchOption.TopDirectoryOnly-тогда это относительно просто, однако-это становится намного сложнее, если вы хотите, чтобы перечислить все файлы рекурсивно с помощью SearchOption.AllDirectories. Если вы можете получить файлы, а затем отфильтровать только для чтения, но, к сожалению, он не будет работать с каталогами, помеченными как скрытые. Файлы в этих папках также отображаются, но они не скрыты в отличие от каталога.
вы можете использовать также GetDirectories, но опять же-вы не можете перечислить все рекурсивно используя searchoption указывает, нужно.AllDirectories, так как он также перечисляет папки, которые находятся в скрытой папке, но эти папки не имеют скрытого атрибута включен.
Это относится, по крайней мере, к Tortoise svn .скрытая папка svn. Он содержит много папок, которые не скрыты, но .СВН скрыта. Наконец, я написал функцию, которая выглядит так:
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 можно использовать параметр в функции при необходимости или удалить, если это не требуется.
мне на самом деле нравится передавать параметр функции методу, который делает то, что я хочу. У меня есть метод SearchDirectory, который является основой для большинства вызовов, которые я использую:
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; }
затем вы можете использовать другие перечисленные решения для записи функции IsHidden, которая принимает один FileInfo и возвращает true, если это так:
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; }
тогда я могу назвать его в другом методе довольно легко:
var files = SearchDirectory(new DirectoryInfo("C:\temp\"), "*.xml", (fi) => { return !IsHidden(fi); );
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); }
действия:
создать bool, который возвращает true, когда строка содержит 'Hidden' - - - -
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()));