.NET ¿Cómo verificar si la ruta es un archivo y no un directorio?

Tengo un camino y necesito determinar si es un directorio o archivo.

¿Es esta la mejor manera de determinar si la ruta es un archivo?

string file = @"C:\Test\foo.txt"; bool isFile = !System.IO.Directory.Exists(file) && System.IO.File.Exists(file); 

Para un directorio invertiría la lógica.

 string directory = @"C:\Test"; bool isDirectory = System.IO.Directory.Exists(directory) && !System.IO.File.Exists(directory); 

Si ambos no existen entonces no iré a ninguna twig. Así que supongamos que ambos existen.

Utilizar:

 System.IO.File.GetAttributes(string path) 

y compruebe si el resultado devuelto FileAttributes contiene el valor FileAttributes.Directory :

 bool isDir = (File.GetAttributes(path) & FileAttributes.Directory) == FileAttributes.Directory; 

Creo que esta es la forma más simple en la que solo necesitas dos controles:

 string file = @"C:\tmp"; if (System.IO.Directory.Exists(file)) { // do stuff when file is an existing directory } else if (System.IO.File.Exists(file)) { // do stuff when file is an existing file } 

Puedes hacer esto con un código de interoperabilidad:

  [DllImport("shlwapi.dll", CharSet = CharSet.Unicode)] [return: MarshalAsAttribute(UnmanagedType.Bool)] public static extern bool PathIsDirectory([MarshalAsAttribute(UnmanagedType.LPWStr), In] string pszPath); 

Para aclarar más algunos de los comentarios …

La introducción de código no administrado en esto ya no es más peligroso que cualquiera de los otros archivos o llamadas relacionadas con E / S en .NET ya que, por último, todos llaman al código no administrado.

Esta es una llamada de función única usando una cadena. No está introduciendo ningún nuevo tipo de datos y / o uso de memoria llamando a esta función. Sí, necesita confiar en el código no administrado para realizar una limpieza adecuada, pero finalmente tiene esa dependencia en la mayoría de las llamadas relacionadas con E / S.

Como referencia, aquí está el código para File.GetAttributes (ruta de cadena) desde Reflector:

 public static FileAttributes GetAttributes(string path) { string fullPathInternal = Path.GetFullPathInternal(path); new FileIOPermission(FileIOPermissionAccess.Read, new string[] { fullPathInternal }, false, false).Demand(); Win32Native.WIN32_FILE_ATTRIBUTE_DATA data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA(); int errorCode = FillAttributeInfo(fullPathInternal, ref data, false, true); if (errorCode != 0) { __Error.WinIOError(errorCode, fullPathInternal); } return (FileAttributes) data.fileAttributes; } 

Como puede ver, también está llamando al código no administrado para recuperar los atributos del archivo, por lo que los argumentos sobre la introducción de código no administrado son peligrosos. Del mismo modo, el argumento acerca de permanecer completamente en el código administrado. No hay implementación de código administrado para hacer esto. Incluso al llamar a File.GetAttributes () como las otras respuestas proponen tienen los mismos “problemas” de llamar al código no administrado y creo que este es el método más confiable para determinar si una ruta es un directorio.

Editar Para responder el comentario de @Christian K sobre CAS. Creo que la única razón por la cual GetAttributes exige la seguridad es porque necesita leer las propiedades del archivo para asegurarse de que el código de llamada tenga permiso para hacerlo. Esto no es lo mismo que las verificaciones del sistema operativo subyacentes (si hay alguna). Siempre puede crear una función envoltura alrededor de la llamada P / Invoke a PathIsDirectory que también exige ciertos permisos CAS, si es necesario.

Suponiendo que el directorio existe …

 bool isDir = (File.GetAttributes(path) & FileAttributes.Directory) == FileAttributes.Directory; 

Mira esto:

 ///  /// Returns true if the given file path is a folder. ///  /// File path /// True if a folder public bool IsFolder(string path) { return ((File.GetAttributes(path) & FileAttributes.Directory) == FileAttributes.Directory); } 

de http://www.jonasjohn.de/snippets/csharp/is-folder.htm

Lee los atributos del archivo:

 FileAttributes att = System.IO.File.GetAttributes(PATH_TO_FILE); 

Compruebe la bandera del directorio .

Dado que una cadena de ruta en particular no puede representar tanto un directorio como un archivo, lo siguiente funciona bien y abre la puerta para otras operaciones.

 bool isFile = new FileInfo(path).Exists; bool isDir = new DirectoryInfo(path).Exists; 

Si está trabajando con el sistema de archivos, usar FileInfo y DirectoryInfo es mucho más simple que usar strings.

Hmm, parece que la clase Files (en java.nio ) en realidad tiene un método isDirectory estático. Entonces, creo que podrías usar lo siguiente:

 Path what = ... boolean isDir = Files.isDirectory(what);