¿Mejor manera de verificar si una ruta es un archivo o un directorio?

383

Estoy procesando una TreeViewde directorios y archivos. Un usuario puede seleccionar un archivo o un directorio y luego hacer algo con él. Esto requiere que tenga un método que realice diferentes acciones basadas en la selección del usuario.

En este momento estoy haciendo algo como esto para determinar si la ruta es un archivo o un directorio:

bool bIsFile = false;
bool bIsDirectory = false;

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

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

¡No puedo evitar sentir que hay una mejor manera de hacer esto! Esperaba encontrar un método .NET estándar para manejar esto, pero no he podido hacerlo. ¿Existe tal método, y si no, cuál es el medio más directo para determinar si una ruta es un archivo o directorio?

SnAzBaZ
fuente
8
¿Alguien puede editar el título de la pregunta para especificar el archivo / directorio "existente" ? Todas las respuestas se aplican a una ruta para un archivo / directorio que está en el disco.
Jake Berger
1
@jberger, consulte mi respuesta a continuación. Encontré una manera de lograr esto para las rutas de archivos / carpetas que pueden o no existir.
lhan
¿Cómo estás poblando esta vista de árbol? ¿Cómo estás sacando el camino?
Random832

Respuestas:

596

De Cómo saber si la ruta es un archivo o directorio :

// 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");

Actualización para .NET 4.0+

Según los comentarios a continuación, si está en .NET 4.0 o posterior (y el rendimiento máximo no es crítico) puede escribir el código de una manera más limpia:

// 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
fuente
8
+1 Este es el mejor enfoque y es significativamente más rápido que la solución que he propuesto.
Andrew Hare
66
@ KeyMs92 Es matemática bit a bit. Básicamente, attr es un valor binario con un bit que significa "este es un directorio". Bitwise y el &operador devolverán un valor binario donde solo se activan los bits que están en (1) en ambos operandos. En este caso, hacer un bit a bit y una operación en contra attry el FileAttributes.Directoryvalor devolverá el valor de FileAttributes.Directorysi el bit de atributo del archivo de Directorio está activado. Ver en.wikipedia.org/wiki/Bitwise_operation para una mejor explicación.
Kyle Trauberman
66
@jberger Si la ruta no existe, entonces es ambiguo si se C:\Temprefiere a un directorio llamado Tempo a un archivo llamado Temp. ¿Qué debe hacer el código?
ta.speot.is
26
@Key: después de .NET 4.0, attr.HasFlag(FileAttributes.Directory)se puede usar en su lugar.
Şafak Gür
13
@ ŞafakGür: No hagas esto dentro de un ciclo sensible al tiempo. attr.HasFlag () es lento como el infierno y usa Reflection para cada llamada
springy76
247

¿Qué hay de usar estos?

File.Exists();
Directory.Exists();
llamaoo7
fuente
43
Esto también tiene la ventaja de no lanzar una excepción en una ruta no válida, a diferencia de File.GetAttributes().
Deanna
Utilizo la biblioteca Long Path de BCL bcl.codeplex.com/… en mi proyecto, por lo que no hay forma de obtener atributos de archivo, pero llamar a Exist es una buena solución.
Puterdo Borato
44
@jberger Esperaría que NO funcione para rutas a archivos / carpetas inexistentes. File.Exists ("c: \\ temp \\ nonexistant.txt") debería devolver false, como lo hace.
michaelkoss
12
Si le preocupan los archivos / carpetas inexistentes, intente esto 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
Más detalles sobre esto están en msdn.microsoft.com/en-us/library/…
Moji
20

Con solo esta línea puede obtener si una ruta es un directorio o un archivo:

File.GetAttributes(data.Path).HasFlag(FileAttributes.Directory)
Canal Gerard Gilabert
fuente
44
Tenga en cuenta que necesita al menos .NET 4.0 para esto. También esto explotará si la ruta no es una ruta válida.
nawfal
Use un objeto FileInfo para verificar si la ruta existe: FileInfo pFinfo = new FileInfo (FList [0]); if (pFinfo.Exists) {if (File.GetAttributes (FList [0]). HasFlag (FileAttributes.Directory)) {}}. Esta funciona para mí.
Michael Stimson
Si ya ha creado un objeto FileInfo y está utilizando la propiedad Exists de la instancia, ¿por qué no acceder a su propiedad Attributes en lugar de utilizar el método estático File.GetAttributes ()?
dynamichael
10

Aquí está el mío:

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

Es similar a las respuestas de otros pero no exactamente igual.

Ronnie Overby
fuente
3
Técnicamente se debe utilizar Path.DirectorySeparatorCharyPath.AltDirectorySeparatorChar
drzaus
1
Esta idea de adivinar la intención es interesante. En mi humilde opinión, es mejor dividir en dos métodos. El Método uno realiza las pruebas de Existencia, devolviendo un booleano anulable. Si la persona que llama quiere la parte "adivinar", en un resultado nulo de Uno, entonces llame al Método Dos, que hace la suposición.
ToolmakerSteve
2
Reescribiría esto para devolver una tupla con si lo adivinó o no.
Ronnie Overby
1
"si tiene extensión es un archivo" - esto no es cierto. Un archivo no tiene que tener una extensión (incluso en Windows) y un directorio puede tener una "extensión". Por ejemplo, este puede ser un archivo o un directorio: "C: \ New folder.log"
bytedev
2
@bytedev Lo sé, pero en ese punto de la función, el código está adivinando la intención. Incluso hay un comentario que lo dice. La mayoría de los archivos tienen una extensión. La mayoría de los directorios no lo hacen.
Ronnie Overby
7

Como alternativa a Directory.Exists (), puede usar el método File.GetAttributes () para obtener los atributos de un archivo o un directorio, por lo que podría crear un método auxiliar como este:

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

También podría considerar agregar un objeto a la propiedad de etiqueta del control TreeView al completar el control que contiene metadatos adicionales para el elemento. Por ejemplo, puede agregar un objeto FileInfo para archivos y un objeto DirectoryInfo para directorios y luego probar el tipo de elemento en la propiedad de etiqueta para guardar haciendo llamadas adicionales al sistema para obtener esos datos al hacer clic en el elemento.

Michael A. McCloskey
fuente
2
¿Cómo es esto diferente a la otra respuesta?
Jake Berger
66
En lugar de ese horrible bloque de lógica, pruebaisDirectory = (fa & FileAttributes.Directory) != 0);
Immortal Blue
5

Esto fue lo mejor que se me ocurrió dado el comportamiento de las propiedades Existe y Atributos:

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

Así es como se prueba:

    [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
fuente
5

Después de combinar las sugerencias de las otras respuestas, me di cuenta de que se me ocurrió casi lo mismo que la respuesta de Ronnie Overby . Aquí hay algunas pruebas para señalar algunas cosas en las que pensar:

  1. Las carpetas pueden tener "extensiones": C:\Temp\folder_with.dot
  2. los archivos no pueden terminar con un separador de directorio (barra inclinada)
  3. Técnicamente, hay dos separadores de directorio que son específicos de la plataforma, es decir, pueden ser barras o no ( Path.DirectorySeparatorChary Path.AltDirectorySeparatorChar)

Pruebas (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);
}

Resultados

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étodo

/// <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
fuente
Path.DirectorySeparatorChar.ToString()en lugar de cadena concat con ""?
Gone Coding
@GoneCoding probablemente; en ese momento había estado trabajando con un montón de propiedades anulables, así que tuve el hábito de "concat con una cadena vacía" en lugar de preocuparme por verificar null. También podría hacer new String(Path.DirectorySeparatorChar, 1)lo que ToStringhace, si quisiera ser realmente optimizado.
drzaus
4

El enfoque más preciso será usar algún código de interoperabilidad de 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);

Entonces lo llamarías así:

#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
fuente
31
Feo. Odio la interoperabilidad para hacer estas tareas simples. Y no es portátil. y es feo ¿Dije que es feo? :)
Ignacio Soler Garcia
55
@SoMoS Puede ser "feo" en su opinión, pero sigue siendo el enfoque más preciso. Sí, no es una solución portátil, pero esa no fue la pregunta que se hizo.
Scott Dorman el
8
¿Qué quieres decir exactamente con precisión? Da los mismos resultados que la respuesta de Quinn Wilson y la interoperabilidad requerida que rompe la portabilidad. Para mí es tan preciso como las otras soluciones y tiene efectos secundarios que otros no tienen.
Ignacio Soler Garcia
77
Hay una API de Framework para hacer esto. Usar Interop no es el camino a seguir.
TomXP411
55
Sí, esto funciona, pero NO es la solución "más precisa", no más que usar el .NET Framework existente. En su lugar, toma 6 líneas de código para reemplazar lo que se puede hacer en una línea con .NET Framework, y se limita a usar solo Windows, en lugar de dejar abierta la capacidad de portar esto con el Proyecto Mono. Nunca use Interop cuando .NET Framework ofrece una solución más elegante.
Russ
2

Esto es lo que usamos:

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
fuente
2

Encontré esto cuando enfrentaba un problema similar, excepto que necesitaba verificar si una ruta es para un archivo o carpeta cuando ese archivo o carpeta realmente no existe . Hubo algunos comentarios sobre las respuestas anteriores que mencionaron que no funcionarían para este escenario. Encontré una solución (uso VB.NET, pero puedes convertirla si es necesario) que parece funcionar bien para mí:

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

¡Espero que esto pueda ser útil para alguien!

lhan
fuente
1
¿Has probado el método Path.HasExtension ?
Jake Berger el
Si no existe, entonces no es un archivo o un directorio. Cualquier nombre se puede crear como cualquiera. Si tiene la intención de crearlo, entonces debe saber lo que está creando, y si no lo hace, ¿por qué podría necesitar esta información?
Random832
8
Una carpeta puede ser nombrado test.txty un archivo puede ser nombrado test- en estos casos, el código sería devolver resultados incorrectos
Stephan Bauer
2
Hay un método .Exists en las clases System.IO.FIle y System.IO.Directory. Eso es lo que hay que hacer. Los directorios pueden tener extensiones; Lo veo con frecuencia.
TomXP411
2

Lo sé muy tarde en el juego, pero pensé que compartiría esto de todos modos. Si solo está trabajando con las rutas como cadenas, descubrir esto es fácil como un pastel:

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

por ejemplo: ThePath == "C:\SomeFolder\File1.txt"terminaría siendo esto:

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

Otro ejemplo: ThePath == "C:\SomeFolder\"terminaría siendo esto:

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

Y esto también funcionaría sin la barra invertida final: ThePath == "C:\SomeFolder"terminaría siendo esto:

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

Tenga en cuenta aquí que esto solo funciona con las rutas en sí mismas, y no con la relación entre la ruta y el "disco físico" ... por lo que no puede decirle si la ruta / archivo existe o algo así, pero seguro puede decirle si la ruta es una carpeta o un archivo ...

MaxOvrdrv
fuente
2
No funciona System.IO.FileSystemWatcherya que cuando se elimina un directorio, se envía c:\my_directorycomo un argumento que es el mismo cuando c:\my_directoryse elimina una extensión sin archivo .
Ray Cheng
GetDirectoryName('C:\SomeFolder')regresa 'C:\', por lo que su último caso no funciona. Esto no distingue entre directorios y archivos sin extensiones.
Lucy
Asume erróneamente que una ruta de directorio siempre incluirá la "\" final. Por ejemplo, Path.GetDirectoryName("C:\SomeFolder\SomeSubFolder")volveremos C:\SomeFolder. Observe que sus propios ejemplos de lo que devuelve GetDirectoryName muestran que devuelve una ruta que no termina en una barra diagonal inversa. Esto significa que si alguien usa GetDirectoryName en otro lugar para obtener una ruta de directorio y luego la alimenta a su método, obtendrá la respuesta incorrecta.
ToolmakerSteve
1

Si desea encontrar directorios, incluidos los que están marcados como "oculto" y "sistema", intente esto (requiere .NET V4):

FileAttributes fa = File.GetAttributes(path);
if(fa.HasFlag(FileAttributes.Directory)) 
jamie
fuente
1

Necesitaba esto, las publicaciones ayudaron, esto lo reduce a una línea, y si la ruta no es una ruta, simplemente regresa y sale del método. Aborda todas las preocupaciones anteriores, tampoco necesita la barra inclinada final.

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

Utilizo lo siguiente, también prueba la extensión, lo que significa que se puede usar para probar si la ruta proporcionada es un archivo pero no existe.

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
fuente
1
FileInfo Extension es (IMAO) una buena opción para verificar rutas inexistentes
dataCore
2
su segunda condición (de lo contrario) es maloliente. si no es un archivo existente, entonces no sabe qué podría ser (los directorios también pueden terminar con algo como ".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
fuente
0

Utilizando la respuesta seleccionada en esta publicación, miré los comentarios y creí a @ ŞafakGür, @Anthony y @Quinn Wilson por sus bits de información que me llevaron a esta respuesta mejorada que escribí y probé:

    /// <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
fuente
Parece un poco derrochador verificar los atributos después de verificar Directorio / Archivo Existe ()? Esas dos llamadas solo hacen todo el trabajo necesario aquí.
Se fue la codificación el
0

Quizás para 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;
    }
Minuto V
fuente
0

Ya veo, llevo 10 años tarde para la fiesta. Estaba enfrentando la situación, donde desde alguna propiedad puedo recibir un nombre de archivo o una ruta de acceso completa. Si no se proporciona una ruta, debo verificar la existencia del archivo adjuntando una ruta de directorio "global" proporcionada por otra propiedad.

En mi caso

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

Hizo el truco. Ok, no es magia, pero quizás esto podría ahorrarle a alguien unos minutos para descubrirlo. Dado que esto es simplemente un análisis de cadenas, los nombres Dir con puntos pueden dar falsos positivos ...

dba
fuente
0

Muy tarde para la fiesta aquí, pero he encontrado que el Nullable<Boolean>valor de retorno es bastante feo: IsDirectory(string path)regresar nullno equivale a una ruta inexistente sin comentarios detallados, por lo que se me ocurrió lo siguiente:

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

Este método auxiliar está escrito para ser lo suficientemente detallado y conciso como para comprender la intención la primera vez que lo lees.

/// <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
fuente
-4

¿No funcionaría esto?

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

fuente
1
Esto no funcionaría solo porque los nombres de carpeta pueden tener puntos en ellos
KSib
Además, los archivos no tienen que tener puntos en ellos.
Keith Pinson