web-dev-qa-db-fra.com

C # - Obtenez une liste des fichiers à l'exclusion de ceux qui sont cachés

Directory.GetFiles() renvoie tous les fichiers, même ceux qui sont marqués comme masqués. Existe-t-il un moyen d'obtenir une liste de fichiers qui exclut les fichiers cachés?

61
James Cadd

Cela devrait fonctionner pour vous:

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);
}
96
Austin Salonen
// check whether a file is hidden
bool isHidden = ((File.GetAttributes(filePath) & FileAttributes.Hidden) == FileAttributes.Hidden);
11
Feedback_looper

En utilisant .NET 4.0 et Directory.EnumerateDirectories, vous pouvez utiliser cette construction:

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

C'est essentiellement la même chose que l'autre réponse, sauf Directory.EnumerateDirectories est un peu plus paresseux. Ce n'est pas très utile si vous énumérez tout, cependant.

(Le let est là pour que la requête soit plus lisible).

8
Jerome Laban

si utilisation, utilisez:

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

cela ne trouve aucun fichier caché, vous pouvez donc utiliser:

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

c'est uniquement pour lire le fichier caché

1
jesus gilbert

En fait, j'aime plutôt passer un paramètre de fonction à une méthode qui fait ce que je veux. J'ai une méthode SearchDirectory, qui constitue la base de la plupart des appels que j'utilise:

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;
}

Ensuite, vous pouvez utiliser les autres solutions répertoriées pour écrire une fonction IsHidden qui prend un seul FileInfo et renvoie true si c'est le cas:

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;
}

Ensuite, je peux l'appeler dans une autre méthode assez facilement:

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

Code sur une ligne:

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

Si vous utilisez SearchOption.TopDirectoryOnly - alors c'est relativement simple, cependant - cela devient beaucoup plus complexe si vous souhaitez répertorier tous les fichiers de manière récursive à l'aide de SearchOption.AllDirectories. Si vous pouvez GetFiles puis filtrer en lecture seule, mais malheureusement, cela ne fonctionnera pas avec les répertoires marqués comme masqués. Les fichiers situés sous ces dossiers sont également répertoriés, mais ils ne sont pas masqués contrairement au répertoire.

Vous pouvez également utiliser GetDirectories, mais encore une fois - vous ne pouvez pas tout répertorier récursivement à l'aide de SearchOption.AllDirectories, car il répertorie également les dossiers qui se trouvent sous le dossier masqué, mais ces dossiers n'ont pas d'attribut masqué activé.

C'est le cas au moins pour le dossier caché Tortoise svn .svn. Il contient de nombreux dossiers qui ne sont pas masqués, mais .svn est masqué. Enfin, j'ai écrit une fonction qui ressemble à ceci:

    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 peut être utilisé un paramètre en fonction si nécessaire ou supprimé s'il n'est pas nécessaire.

1
TarmoPikaro