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 и Directory.EnumerateDirectories, вы можете использовать эту конструкцию:
var hiddenFilesQuery = from file in Directory.EnumerateDirectories(@"c:\temp")
let info = new FileInfo(file)
where (info.Attributes & FileAttributes.Hidden) == 0
select file;
Это в основном то же самое, что и другой ответ, за исключением того, что Directory.EnumerateDirectories немного ленивее. Это не очень полезно, если вы все перечисляете.
(Позвольте здесь иметь запрос, но более понятный).
если использовать использовать:
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();
Я на самом деле скорее люблю передавать параметр функции в метод, который делает то, что я хочу. У меня есть метод 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); );
Если вы используете SearchOption.TopDirectoryOnly - тогда это относительно просто, однако - становится намного сложнее, если вы хотите рекурсивно перечислять все файлы с помощью SearchOption.AllDirectories. Если вы можете GetFiles, а затем отфильтровать только для чтения, но, к сожалению, он не будет работать с каталогами, помеченными как скрытые. Файлы в этих папках также отображаются в списке, но они не скрыты в отличие от каталога.
Вы также можете использовать GetDirectories, но опять же - вы не можете перечислить все рекурсивно, используя SearchOption.AllDirectories, поскольку в нем также перечислены папки, которые находятся в скрытой папке, но в этих папках не включен скрытый атрибут.
Это как минимум случай со скрытой папкой Tortoise SVN.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 может быть использован параметр в функции, если это необходимо, или удалить, если не нужно.
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()));