Une meilleure façon de vérifier si un chemin est un fichier ou un répertoire?

383

Je traite un TreeViewdes répertoires et des fichiers. Un utilisateur peut sélectionner un fichier ou un répertoire, puis en faire quelque chose. Cela nécessite que je dispose d'une méthode qui effectue différentes actions en fonction de la sélection de l'utilisateur.

En ce moment, je fais quelque chose comme ça pour déterminer si le chemin est un fichier ou un répertoire:

bool bIsFile = false;
bool bIsDirectory = false;

try
{
    string[] subfolders = Directory.GetDirectories(strFilePath);

    bIsDirectory = true;
    bIsFile = false;
}
catch(System.IO.IOException)
{
    bIsFolder = false;
    bIsFile = true;
}

Je ne peux m'empêcher de penser qu'il existe une meilleure façon de procéder! J'espérais trouver une méthode .NET standard pour gérer cela, mais je n'ai pas pu le faire. Existe-t-il une telle méthode et sinon, quel est le moyen le plus simple pour déterminer si un chemin est un fichier ou un répertoire?

SnAzBaZ
la source
8
Quelqu'un peut-il modifier le titre de la question pour spécifier le fichier / répertoire "existant" ? Toutes les réponses s'appliquent à un chemin d'accès à un fichier / répertoire qui se trouve sur le disque.
Jake Berger
1
@jberger veuillez vous référer à ma réponse ci-dessous. J'ai trouvé un moyen d'y parvenir pour les chemins de fichiers / dossiers qui peuvent ou non exister.
lhan
Comment remplissez-vous cette arborescence? Comment en tirez-vous le chemin?
Random832

Réponses:

596

De Comment savoir si le chemin est un fichier ou un répertoire :

// get the file attributes for file or directory
FileAttributes attr = File.GetAttributes(@"c:\Temp");

//detect whether its a directory or file
if ((attr & FileAttributes.Directory) == FileAttributes.Directory)
    MessageBox.Show("Its a directory");
else
    MessageBox.Show("Its a file");

Mise à jour pour .NET 4.0+

Selon les commentaires ci-dessous, si vous êtes sur .NET 4.0 ou version ultérieure (et que les performances maximales ne sont pas critiques), vous pouvez écrire le code d'une manière plus propre:

// get the file attributes for file or directory
FileAttributes attr = File.GetAttributes(@"c:\Temp");

if (attr.HasFlag(FileAttributes.Directory))
    MessageBox.Show("Its a directory");
else
    MessageBox.Show("Its a file");
Quinn Wilson
la source
8
+1 C'est la meilleure approche et elle est nettement plus rapide que la solution que j'ai proposée.
Andrew Hare le
6
@ KeyMs92 Son calcul au niveau du bit. Fondamentalement, attr est une valeur binaire avec un bit signifiant "ceci est un répertoire". L' &opérateur au niveau du bit et retournera une valeur binaire où seuls les bits qui sont activés (1) dans les deux opérandes sont activés. Dans ce cas, effectuer une opération au niveau du bit et contre attret la FileAttributes.Directoryvaleur renverra la valeur de FileAttributes.Directorysi le bit d'attribut de fichier d'annuaire est activé. Voir en.wikipedia.org/wiki/Bitwise_operation pour une meilleure explication.
Kyle Trauberman
6
@jberger Si le chemin n'existe pas, il est ambigu qu'il fasse C:\Tempréférence à un répertoire appelé Tempou à un fichier appelé Temp. À quoi sert le code?
ta.speot.is
26
@Key: Après .NET 4.0, attr.HasFlag(FileAttributes.Directory)peut être utilisé à la place.
Şafak Gür
13
@ ŞafakGür: Ne faites pas cela dans une boucle sensible au temps. attr.HasFlag () est lent comme l'enfer et utilise la réflexion pour chaque appel
springy76
247

Que diriez-vous de les utiliser?

File.Exists();
Directory.Exists();
llamaoo7
la source
43
Cela a également l'avantage de ne pas lancer d'exception sur un chemin non valide, contrairement à File.GetAttributes().
Deanna
J'utilise la bibliothèque Long Path de BCL bcl.codeplex.com/… dans mon projet, il n'y a donc aucun moyen d'obtenir des attributs de fichier, mais appeler Exist est une bonne solution de contournement.
Puterdo Borato
4
@jberger Je m'attendrais à ce qu'il ne fonctionne PAS pour les chemins vers des fichiers / dossiers inexistants. File.Exists ("c: \\ temp \\ nonexistant.txt") doit renvoyer false, comme il le fait.
michaelkoss
12
Si vous êtes préoccupé par des fichiers / dossiers inexistants, essayez ceci public static bool? IsDirectory(string path){ if (Directory.Exists(path)) return true; // is a directory else if (File.Exists(path)) return false; // is a file else return null; // is a nothing }
Dustin Townsend
1
Plus de détails à ce sujet sont disponibles sur msdn.microsoft.com/en-us/library/…
Moji
20

Avec seulement cette ligne, vous pouvez obtenir si un chemin est un répertoire ou un fichier:

File.GetAttributes(data.Path).HasFlag(FileAttributes.Directory)
Canal Gerard Gilabert
la source
4
Attention, vous avez besoin d'au moins .NET 4.0 pour cela. Cela explosera également si le chemin n'est pas un chemin valide.
nawfal
Utilisez un objet FileInfo pour vérifier si le chemin existe: FileInfo pFinfo = new FileInfo (FList [0]); if (pFinfo.Exists) {if (File.GetAttributes (FList [0]). HasFlag (FileAttributes.Directory)) {}}. Celui-ci fonctionne pour moi.
Michael Stimson
Si vous avez déjà créé un objet FileInfo et utilisez la propriété Exists de l'instance, pourquoi ne pas accéder à sa propriété Attributes au lieu d'utiliser la méthode statique File.GetAttributes ()?
dynamichael
10

Voici la mienne:

    bool IsPathDirectory(string path)
    {
        if (path == null) throw new ArgumentNullException("path");
        path = path.Trim();

        if (Directory.Exists(path)) 
            return true;

        if (File.Exists(path)) 
            return false;

        // neither file nor directory exists. guess intention

        // if has trailing slash then it's a directory
        if (new[] {"\\", "/"}.Any(x => path.EndsWith(x)))
            return true; // ends with slash

        // if has extension then its a file; directory otherwise
        return string.IsNullOrWhiteSpace(Path.GetExtension(path));
    }

C'est similaire aux réponses des autres mais pas exactement la même chose.

Ronnie Overby
la source
3
Techniquement, vous devez utiliser Path.DirectorySeparatorCharetPath.AltDirectorySeparatorChar
drzaus
1
Cette idée de deviner l'intention est intéressante. À mon humble avis mieux de se diviser en deux méthodes. La première méthode effectue les tests d'existence et renvoie un booléen nullable. Si l'appelant veut alors la partie "deviner", sur un résultat nul de Un, appelez alors la Méthode Deux, qui fait la devinette.
ToolmakerSteve
2
Je réécrirais ceci pour retourner un tuple avec s'il a deviné ou non.
Ronnie Overby du
1
"si a une extension, alors c'est un fichier" - ce n'est pas vrai. Un fichier n'a pas besoin d'avoir une extension (même sous Windows) et un répertoire peut avoir une "extension". Par exemple, cela peut être un fichier ou un répertoire: "C: \ New folder.log"
bytedev
2
@bytedev Je le sais, mais à ce stade de la fonction, le code est une intention de devinette. Il y a même un commentaire le disant. La plupart des fichiers ont une extension. La plupart des répertoires ne le font pas.
Ronnie Overby
7

Comme alternative à Directory.Exists (), vous pouvez utiliser la méthode File.GetAttributes () pour obtenir les attributs d'un fichier ou d'un répertoire, vous pouvez donc créer une méthode d'assistance comme celle-ci:

private static bool IsDirectory(string path)
{
    System.IO.FileAttributes fa = System.IO.File.GetAttributes(path);
    return (fa & FileAttributes.Directory) != 0;
}

Vous pouvez également envisager d'ajouter un objet à la propriété de balise du contrôle TreeView lors du remplissage du contrôle qui contient des métadonnées supplémentaires pour l'élément. Par exemple, vous pouvez ajouter un objet FileInfo pour les fichiers et un objet DirectoryInfo pour les répertoires, puis tester le type d'élément dans la propriété de balise pour enregistrer les appels système supplémentaires pour obtenir ces données lorsque vous cliquez sur l'élément.

Michael A. McCloskey
la source
2
en quoi est-ce différent de l'autre réponse
Jake Berger
6
Plutôt que cet horrible bloc de logique, essayezisDirectory = (fa & FileAttributes.Directory) != 0);
Immortal Blue
5

C'était le meilleur que j'ai pu trouver étant donné le comportement des propriétés Exists et Attributes:

using System.IO;

public static class FileSystemInfoExtensions
{
    /// <summary>
    /// Checks whether a FileInfo or DirectoryInfo object is a directory, or intended to be a directory.
    /// </summary>
    /// <param name="fileSystemInfo"></param>
    /// <returns></returns>
    public static bool IsDirectory(this FileSystemInfo fileSystemInfo)
    {
        if (fileSystemInfo == null)
        {
            return false;
        }

        if ((int)fileSystemInfo.Attributes != -1)
        {
            // if attributes are initialized check the directory flag
            return fileSystemInfo.Attributes.HasFlag(FileAttributes.Directory);
        }

        // If we get here the file probably doesn't exist yet.  The best we can do is 
        // try to judge intent.  Because directories can have extensions and files
        // can lack them, we can't rely on filename.
        // 
        // We can reasonably assume that if the path doesn't exist yet and 
        // FileSystemInfo is a DirectoryInfo, a directory is intended.  FileInfo can 
        // make a directory, but it would be a bizarre code path.

        return fileSystemInfo is DirectoryInfo;
    }
}

Voici comment il teste:

    [TestMethod]
    public void IsDirectoryTest()
    {
        // non-existing file, FileAttributes not conclusive, rely on type of FileSystemInfo
        const string nonExistentFile = @"C:\TotallyFakeFile.exe";

        var nonExistentFileDirectoryInfo = new DirectoryInfo(nonExistentFile);
        Assert.IsTrue(nonExistentFileDirectoryInfo.IsDirectory());

        var nonExistentFileFileInfo = new FileInfo(nonExistentFile);
        Assert.IsFalse(nonExistentFileFileInfo.IsDirectory());

        // non-existing directory, FileAttributes not conclusive, rely on type of FileSystemInfo
        const string nonExistentDirectory = @"C:\FakeDirectory";

        var nonExistentDirectoryInfo = new DirectoryInfo(nonExistentDirectory);
        Assert.IsTrue(nonExistentDirectoryInfo.IsDirectory());

        var nonExistentFileInfo = new FileInfo(nonExistentDirectory);
        Assert.IsFalse(nonExistentFileInfo.IsDirectory());

        // Existing, rely on FileAttributes
        const string existingDirectory = @"C:\Windows";

        var existingDirectoryInfo = new DirectoryInfo(existingDirectory);
        Assert.IsTrue(existingDirectoryInfo.IsDirectory());

        var existingDirectoryFileInfo = new FileInfo(existingDirectory);
        Assert.IsTrue(existingDirectoryFileInfo.IsDirectory());

        // Existing, rely on FileAttributes
        const string existingFile = @"C:\Windows\notepad.exe";

        var existingFileDirectoryInfo = new DirectoryInfo(existingFile);
        Assert.IsFalse(existingFileDirectoryInfo.IsDirectory());

        var existingFileFileInfo = new FileInfo(existingFile);
        Assert.IsFalse(existingFileFileInfo.IsDirectory());
    }
HAL9000
la source
5

Après avoir combiné les suggestions des autres réponses, j'ai réalisé que j'avais trouvé la même chose que la réponse de Ronnie Overby . Voici quelques tests pour souligner certaines choses à penser:

  1. les dossiers peuvent avoir des "extensions": C:\Temp\folder_with.dot
  2. les fichiers ne peuvent pas se terminer par un séparateur de répertoires (barre oblique)
  3. Il existe techniquement deux séparateurs de répertoires spécifiques à la plate-forme, c'est-à-dire qu'ils peuvent ou non être des barres obliques ( Path.DirectorySeparatorCharet Path.AltDirectorySeparatorChar)

Tests (Linqpad)

var paths = new[] {
    // exists
    @"C:\Temp\dir_test\folder_is_a_dir",
    @"C:\Temp\dir_test\is_a_dir_trailing_slash\",
    @"C:\Temp\dir_test\existing_folder_with.ext",
    @"C:\Temp\dir_test\file_thats_not_a_dir",
    @"C:\Temp\dir_test\notadir.txt",
    // doesn't exist
    @"C:\Temp\dir_test\dne_folder_is_a_dir",
    @"C:\Temp\dir_test\dne_folder_trailing_slash\",
    @"C:\Temp\dir_test\non_existing_folder_with.ext",
    @"C:\Temp\dir_test\dne_file_thats_not_a_dir",
    @"C:\Temp\dir_test\dne_notadir.txt",        
};

foreach(var path in paths) {
    IsFolder(path/*, false*/).Dump(path);
}

Résultats

C:\Temp\dir_test\folder_is_a_dir
  True 
C:\Temp\dir_test\is_a_dir_trailing_slash\
  True 
C:\Temp\dir_test\existing_folder_with.ext
  True 
C:\Temp\dir_test\file_thats_not_a_dir
  False 
C:\Temp\dir_test\notadir.txt
  False 
C:\Temp\dir_test\dne_folder_is_a_dir
  True 
C:\Temp\dir_test\dne_folder_trailing_slash\
  True 
C:\Temp\dir_test\non_existing_folder_with.ext
  False (this is the weird one)
C:\Temp\dir_test\dne_file_thats_not_a_dir
  True 
C:\Temp\dir_test\dne_notadir.txt
  False 

Méthode

/// <summary>
/// Whether the <paramref name="path"/> is a folder (existing or not); 
/// optionally assume that if it doesn't "look like" a file then it's a directory.
/// </summary>
/// <param name="path">Path to check</param>
/// <param name="assumeDneLookAlike">If the <paramref name="path"/> doesn't exist, does it at least look like a directory name?  As in, it doesn't look like a file.</param>
/// <returns><c>True</c> if a folder/directory, <c>false</c> if not.</returns>
public static bool IsFolder(string path, bool assumeDneLookAlike = true)
{
    // /programming/1395205/better-way-to-check-if-path-is-a-file-or-a-directory
    // turns out to be about the same as https://stackoverflow.com/a/19596821/1037948

    // check in order of verisimilitude

    // exists or ends with a directory separator -- files cannot end with directory separator, right?
    if (Directory.Exists(path)
        // use system values rather than assume slashes
        || path.EndsWith("" + Path.DirectorySeparatorChar)
        || path.EndsWith("" + Path.AltDirectorySeparatorChar))
        return true;

    // if we know for sure that it's an actual file...
    if (File.Exists(path))
        return false;

    // if it has an extension it should be a file, so vice versa
    // although technically directories can have extensions...
    if (!Path.HasExtension(path) && assumeDneLookAlike)
        return true;

    // only works for existing files, kinda redundant with `.Exists` above
    //if( File.GetAttributes(path).HasFlag(FileAttributes.Directory) ) ...; 

    // no idea -- could return an 'indeterminate' value (nullable bool)
    // or assume that if we don't know then it's not a folder
    return false;
}
drzaus
la source
Path.DirectorySeparatorChar.ToString()au lieu de concaténer la chaîne avec ""?
Fin du codage
@GoneCoding probablement; à l'époque, je travaillais avec un tas de propriétés nullables donc j'ai pris l'habitude de "concat avec une chaîne vide" plutôt que de m'inquiéter de vérifier null. Vous pouvez également faire new String(Path.DirectorySeparatorChar, 1)ce ToStringque vous voulez, si vous voulez vraiment être optimisé.
drzaus
4

L'approche la plus précise va utiliser du code d'interopérabilité du shlwapi.dll

[DllImport(SHLWAPI, CharSet = CharSet.Unicode)]
[return: MarshalAsAttribute(UnmanagedType.Bool)]
[ResourceExposure(ResourceScope.None)]
internal static extern bool PathIsDirectory([MarshalAsAttribute(UnmanagedType.LPWStr), In] string pszPath);

Vous l'appeleriez alors comme ceci:

#region IsDirectory
/// <summary>
/// Verifies that a path is a valid directory.
/// </summary>
/// <param name="path">The path to verify.</param>
/// <returns><see langword="true"/> if the path is a valid directory; 
/// otherwise, <see langword="false"/>.</returns>
/// <exception cref="T:System.ArgumentNullException">
/// <para><paramref name="path"/> is <see langword="null"/>.</para>
/// </exception>
/// <exception cref="T:System.ArgumentException">
/// <para><paramref name="path"/> is <see cref="F:System.String.Empty">String.Empty</see>.</para>
/// </exception>
public static bool IsDirectory(string path)
{
    return PathIsDirectory(path);
}
Scott Dorman
la source
31
Laid. Je déteste l'interopérabilité pour effectuer ces tâches simples. Et ce n'est pas portable. et c'est moche. Ai-je dit que c'était moche? :)
Ignacio Soler Garcia
5
@SoMoS C'est peut-être "moche" à votre avis, mais c'est toujours l'approche la plus précise. Oui, ce n'est pas une solution portable mais ce n'était pas ce que la question demandait.
Scott Dorman
8
Que voulez-vous dire exactement avec précision? Il donne les mêmes résultats que la réponse de Quinn Wilson et l'interopérabilité requise qui rompt la portabilité. Pour moi, c'est aussi précis que les autres solutions et avoir des effets secondaires que d'autres n'ont pas.
Ignacio Soler Garcia
7
Il existe une API Framework pour ce faire. Utiliser Interop n'est pas la voie à suivre.
TomXP411
5
Oui, cela fonctionne, mais ce n'est PAS la solution "la plus précise" - pas plus que l'utilisation du .NET Framework existant. Au lieu de cela, vous prenez 6 lignes de code pour remplacer ce qui peut être fait sur une seule ligne avec le .NET Framework, et vous enfermez dans l'utilisation de Windows uniquement, au lieu de laisser ouverte la possibilité de le porter avec le projet Mono. N'utilisez jamais Interop lorsque le .NET Framework offre une solution plus élégante.
Russ
2

Voici ce que nous utilisons:

using System;

using System.IO;

namespace crmachine.CommonClasses
{

  public static class CRMPath
  {

    public static bool IsDirectory(string path)
    {
      if (path == null)
      {
        throw new ArgumentNullException("path");
      }

      string reason;
      if (!IsValidPathString(path, out reason))
      {
        throw new ArgumentException(reason);
      }

      if (!(Directory.Exists(path) || File.Exists(path)))
      {
        throw new InvalidOperationException(string.Format("Could not find a part of the path '{0}'",path));
      }

      return (new System.IO.FileInfo(path).Attributes & FileAttributes.Directory) == FileAttributes.Directory;
    } 

    public static bool IsValidPathString(string pathStringToTest, out string reasonForError)
    {
      reasonForError = "";
      if (string.IsNullOrWhiteSpace(pathStringToTest))
      {
        reasonForError = "Path is Null or Whitespace.";
        return false;
      }
      if (pathStringToTest.Length > CRMConst.MAXPATH) // MAXPATH == 260
      {
        reasonForError = "Length of path exceeds MAXPATH.";
        return false;
      }
      if (PathContainsInvalidCharacters(pathStringToTest))
      {
        reasonForError = "Path contains invalid path characters.";
        return false;
      }
      if (pathStringToTest == ":")
      {
        reasonForError = "Path consists of only a volume designator.";
        return false;
      }
      if (pathStringToTest[0] == ':')
      {
        reasonForError = "Path begins with a volume designator.";
        return false;
      }

      if (pathStringToTest.Contains(":") && pathStringToTest.IndexOf(':') != 1)
      {
        reasonForError = "Path contains a volume designator that is not part of a drive label.";
        return false;
      }
      return true;
    }

    public static bool PathContainsInvalidCharacters(string path)
    {
      if (path == null)
      {
        throw new ArgumentNullException("path");
      }

      bool containedInvalidCharacters = false;

      for (int i = 0; i < path.Length; i++)
      {
        int n = path[i];
        if (
            (n == 0x22) || // "
            (n == 0x3c) || // <
            (n == 0x3e) || // >
            (n == 0x7c) || // |
            (n  < 0x20)    // the control characters
          )
        {
          containedInvalidCharacters = true;
        }
      }

      return containedInvalidCharacters;
    }


    public static bool FilenameContainsInvalidCharacters(string filename)
    {
      if (filename == null)
      {
        throw new ArgumentNullException("filename");
      }

      bool containedInvalidCharacters = false;

      for (int i = 0; i < filename.Length; i++)
      {
        int n = filename[i];
        if (
            (n == 0x22) || // "
            (n == 0x3c) || // <
            (n == 0x3e) || // >
            (n == 0x7c) || // |
            (n == 0x3a) || // : 
            (n == 0x2a) || // * 
            (n == 0x3f) || // ? 
            (n == 0x5c) || // \ 
            (n == 0x2f) || // /
            (n  < 0x20)    // the control characters
          )
        {
          containedInvalidCharacters = true;
        }
      }

      return containedInvalidCharacters;
    }

  }

}
PMBottas
la source
2

Je suis tombé sur ce problème face à un problème similaire, sauf que je devais vérifier si un chemin est pour un fichier ou un dossier lorsque ce fichier ou ce dossier peut ne pas exister . Il y a eu quelques commentaires sur les réponses ci-dessus qui ont mentionné qu'ils ne fonctionneraient pas pour ce scénario. J'ai trouvé une solution (j'utilise VB.NET, mais vous pouvez convertir si vous en avez besoin) qui semble bien fonctionner pour moi:

Dim path As String = "myFakeFolder\ThisDoesNotExist\"
Dim bIsFolder As Boolean = (IO.Path.GetExtension(path) = "")
'returns True

Dim path As String = "myFakeFolder\ThisDoesNotExist\File.jpg"
Dim bIsFolder As Boolean = (IO.Path.GetExtension(path) = "")
'returns False

J'espère que cela peut être utile à quelqu'un!

lhan
la source
1
avez-vous essayé la méthode Path.HasExtension ?
Jake Berger
S'il n'existe pas, ce n'est pas un fichier ou un répertoire. N'importe quel nom peut être créé comme l'un ou l'autre. Si vous avez l'intention de le créer, alors vous devez savoir ce que vous créez, et si vous ne le faites pas, alors pourquoi pourriez-vous éventuellement avoir besoin de ces informations?
Random832
8
Un dossier peut être nommé test.txtet un fichier peut être nommé test- dans ces cas, votre code retournerait des résultats incorrects
Stephan Bauer
2
Il existe une méthode .Exists dans les classes System.IO.FIle et System.IO.Directory. c'est la chose à faire. Les répertoires peuvent avoir des extensions; Je le vois fréquemment.
TomXP411
2

tellement tard dans le jeu, je sais, mais j'ai pensé que je partagerais ça quand même. Si vous travaillez uniquement avec les chemins sous forme de chaînes, il est facile de comprendre cela:

private bool IsFolder(string ThePath)
{
    string BS = Path.DirectorySeparatorChar.ToString();
    return Path.GetDirectoryName(ThePath) == ThePath.TrimEnd(BS.ToCharArray());
}

par exemple: ThePath == "C:\SomeFolder\File1.txt"finirait par être ceci:

return "C:\SomeFolder" == "C:\SomeFolder\File1.txt" (FALSE)

Un autre exemple: ThePath == "C:\SomeFolder\"finirait par être le suivant:

return "C:\SomeFolder" == "C:\SomeFolder" (TRUE)

Et cela fonctionnerait également sans la barre oblique inverse: ThePath == "C:\SomeFolder"finirait par être ceci:

return "C:\SomeFolder" == "C:\SomeFolder" (TRUE)

Gardez à l'esprit ici que cela ne fonctionne qu'avec les chemins eux-mêmes, et non la relation entre le chemin et le "disque physique" ... donc il ne peut pas vous dire si le chemin / fichier existe ou quelque chose comme ça, mais c'est sûr peut vous dire si le chemin est un dossier ou un fichier ...

MaxOvrdrv
la source
2
Ne fonctionne pas avec, System.IO.FileSystemWatchercar lorsqu'un répertoire est supprimé, il envoie c:\my_directoryun argument qui est le même lorsqu'un fichier c:\my_directorysans extension est supprimé.
Ray Cheng
GetDirectoryName('C:\SomeFolder')revient 'C:\', donc votre dernier cas ne fonctionne pas. Cela ne fait pas de distinction entre les répertoires et les fichiers sans extension.
Lucy
Vous supposez à tort qu'un chemin de répertoire inclura toujours le "\" final. Par exemple, Path.GetDirectoryName("C:\SomeFolder\SomeSubFolder")reviendra C:\SomeFolder. Notez que vos propres exemples de ce que GetDirectoryName retourne montrent qu'il renvoie un chemin d'accès qui ne se termine pas par une barre oblique inverse. Cela signifie que si quelqu'un utilise GetDirectoryName ailleurs pour obtenir un chemin de répertoire, puis le transmet à votre méthode, il obtiendra la mauvaise réponse.
ToolmakerSteve
1

Si vous souhaitez trouver des répertoires, y compris ceux qui sont marqués "cachés" et "système", essayez ceci (nécessite .NET V4):

FileAttributes fa = File.GetAttributes(path);
if(fa.HasFlag(FileAttributes.Directory)) 
Jamie
la source
1

J'en avais besoin, les messages ont aidé, cela le ramène à une seule ligne, et si le chemin n'est pas du tout un chemin, il revient simplement et quitte la méthode. Il répond à toutes les préoccupations ci-dessus, n'a pas besoin non plus de la barre oblique de fin.

if (!Directory.Exists(@"C:\folderName")) return;
Joe Stellato
la source
0

J'utilise ce qui suit, il teste également l'extension, ce qui signifie qu'elle peut être utilisée pour tester si le chemin fourni est un fichier mais un fichier qui n'existe pas.

private static bool isDirectory(string path)
{
    bool result = true;
    System.IO.FileInfo fileTest = new System.IO.FileInfo(path);
    if (fileTest.Exists == true)
    {
        result = false;
    }
    else
    {
        if (fileTest.Extension != "")
        {
            result = false;
        }
    }
    return result;
}
Stu1983
la source
1
L'extension FileInfo est (IMAO) une bonne option pour vérifier les chemins inexistants
dataCore
2
votre deuxième condition (sinon) est malodorante. s'il ne s'agit pas d'un fichier existant, vous ne savez pas ce qu'il pourrait être (les répertoires peuvent également se terminer par quelque chose comme ".txt").
nawfal
0
using System;
using System.IO;
namespace FileOrDirectory
{
     class Program
     {
          public static string FileOrDirectory(string path)
          {
               if (File.Exists(path))
                    return "File";
               if (Directory.Exists(path))
                    return "Directory";
               return "Path Not Exists";
          }
          static void Main()
          {
               Console.WriteLine("Enter The Path:");
               string path = Console.ReadLine();
               Console.WriteLine(FileOrDirectory(path));
          }
     }
}
Diaa Eddin
la source
0

En utilisant la réponse sélectionnée sur ce post, j'ai regardé les commentaires et j'ai rendu hommage à @ ŞafakGür, @Anthony et @Quinn Wilson pour leurs informations qui m'ont conduit à cette réponse améliorée que j'ai écrite et testée:

    /// <summary>
    /// Returns true if the path is a dir, false if it's a file and null if it's neither or doesn't exist.
    /// </summary>
    /// <param name="path"></param>
    /// <returns></returns>
    public static bool? IsDirFile(this string path)
    {
        bool? result = null;

        if(Directory.Exists(path) || File.Exists(path))
        {
            // get the file attributes for file or directory
            var fileAttr = File.GetAttributes(path);

            if (fileAttr.HasFlag(FileAttributes.Directory))
                result = true;
            else
                result = false;
        }

        return result;
    }
Mike Socha III
la source
Semble un peu inutile de vérifier les attributs après avoir déjà vérifié l'existence du répertoire / fichier ()? Ces deux appels à eux seuls font tout le travail nécessaire ici.
Fin du codage
0

Peut-être pour UWP C #

public static async Task<IStorageItem> AsIStorageItemAsync(this string iStorageItemPath)
    {
        if (string.IsNullOrEmpty(iStorageItemPath)) return null;
        IStorageItem storageItem = null;
        try
        {
            storageItem = await StorageFolder.GetFolderFromPathAsync(iStorageItemPath);
            if (storageItem != null) return storageItem;
        } catch { }
        try
        {
            storageItem = await StorageFile.GetFileFromPathAsync(iStorageItemPath);
            if (storageItem != null) return storageItem;
        } catch { }
        return storageItem;
    }
Minute V
la source
0

Je vois, j'ai 10 ans de retard pour la fête. J'étais confronté à la situation, où à partir d'une propriété, je peux recevoir un nom de fichier ou un chemin de fichier complet. S'il n'y a pas de chemin fourni, je dois vérifier l'existence du fichier en attachant un chemin de répertoire "global" fourni par une autre propriété.

Dans mon cas

var isFileName = System.IO.Path.GetFileName (str) == str;

a fait l'affaire. D'accord, ce n'est pas magique, mais cela pourrait peut-être faire gagner quelques minutes à quelqu'un. Comme il s'agit simplement d'une analyse de chaîne, les noms Dir avec des points peuvent donner des faux positifs ...

dba
la source
0

Très tard pour la fête ici, mais j'ai trouvé la Nullable<Boolean>valeur de retour assez moche - le IsDirectory(string path)retour nulln'équivaut pas à un chemin inexistant sans commentaire détaillé, j'ai donc trouvé ce qui suit:

public static class PathHelper
{
    /// <summary>
    /// Determines whether the given path refers to an existing file or directory on disk.
    /// </summary>
    /// <param name="path">The path to test.</param>
    /// <param name="isDirectory">When this method returns, contains true if the path was found to be an existing directory, false in all other scenarios.</param>
    /// <returns>true if the path exists; otherwise, false.</returns>
    /// <exception cref="ArgumentNullException">If <paramref name="path"/> is null.</exception>
    /// <exception cref="ArgumentException">If <paramref name="path"/> equals <see cref="string.Empty"/></exception>
    public static bool PathExists(string path, out bool isDirectory)
    {
        if (path == null) throw new ArgumentNullException(nameof(path));
        if (path == string.Empty) throw new ArgumentException("Value cannot be empty.", nameof(path));

        isDirectory = Directory.Exists(path);

        return isDirectory || File.Exists(path);
    }
}

Cette méthode d'aide est écrite pour être suffisamment verbeuse et concise pour comprendre l'intention la première fois que vous la lisez.

/// <summary>
/// Example usage of <see cref="PathExists(string, out bool)"/>
/// </summary>
public static void Usage()
{
    const string path = @"C:\dev";

    if (!PathHelper.PathExists(path, out var isDirectory))
        return;

    if (isDirectory)
    {
        // Do something with your directory
    }
    else
    {
        // Do something with your file
    }
}
martinthebeardy
la source
-4

Cela ne fonctionnerait-il pas?

var isFile = Regex.IsMatch(path, @"\w{1,}\.\w{1,}$");

la source
1
Cela ne fonctionnerait pas uniquement parce que les noms de dossier peuvent
contenir des points
Les fichiers ne doivent pas non plus avoir de points.
Keith Pinson