.NET. Как проверить, является ли путь файлом, а не каталогом?
У меня есть путь, и мне нужно определить, является ли он каталогом или файлом.
Это лучший способ определить, является ли путь файлом?
string file = @"C:\Test\foo.txt";
bool isFile = !System.IO.Directory.Exists(file) &&
System.IO.File.Exists(file);
Для каталога я бы отменил логику.
string directory = @"C:\Test";
bool isDirectory = System.IO.Directory.Exists(directory) &&
!System.IO.File.Exists(directory);
Если оба не существуют, то я не пойду ни на одну ветвь. Поэтому предположим, что они оба существуют.
Ответы
Ответ 1
Использование:
System.IO.File.GetAttributes(string path)
и проверьте, содержит ли возвращаемый результат FileAttributes
значение FileAttributes.Directory
:
bool isDir = (File.GetAttributes(path) & FileAttributes.Directory)
== FileAttributes.Directory;
Ответ 2
Я думаю, что это самый простой способ, когда вам нужны только две проверки:
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
}
Ответ 3
Вы можете сделать это с помощью некоторого кода взаимодействия:
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
[return: MarshalAsAttribute(UnmanagedType.Bool)]
public static extern bool PathIsDirectory([MarshalAsAttribute(UnmanagedType.LPWStr), In] string pszPath);
Чтобы прояснить некоторые комментарии...
Внедрение неуправляемого кода в этом уже не является наследованием опасным, чем любые другие вызовы, связанные с файлом или I/O в .NET, поскольку они ультиматулируют все вызовы в неуправляемый код.
Это один вызов функции с использованием строки. Вы не вводите новые типы данных и/или использование памяти, вызывая эту функцию. Да, вам нужно полагаться на неуправляемый код для правильной очистки, но в конечном итоге вы зависите от большинства вызовов, связанных с I/O.
Для справки, вот код в File.GetAttributes(путь строки) от 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;
}
Как вы можете видеть, он также вызывает неуправляемый код для извлечения атрибутов файла, поэтому аргументы в отношении введения неуправляемого кода являются опасными. Аналогичным образом, аргумент о полном пребывании в управляемом коде. Для этого не существует управляемой реализации кода. Даже вызывая File.GetAttributes(), поскольку другие ответы предлагают иметь те же "проблемы" для вызова неперечисленного кода, и я считаю, что это более надежный метод для определения того, является ли путь каталогом.
Изменить. Ответьте на комментарий @Christian K о CAS. Я считаю, что единственная причина, по которой GetAttributes делает требование безопасности, заключается в том, что ему нужно прочитать свойства файла, чтобы он хотел убедиться, что у вызывающего кода есть разрешение на это. Это не то же самое, что основные проверки ОС (если они есть). Вы всегда можете создать функцию обертки вокруг вызова P/Invoke в PathIsDirectory, который также требует определенных разрешений CAS, если это необходимо.
Ответ 4
Предполагая, что каталог существует...
bool isDir = (File.GetAttributes(path) & FileAttributes.Directory)
== FileAttributes.Directory;
Ответ 5
Проверьте это:
/// <summary>
/// Returns true if the given file path is a folder.
/// </summary>
/// <param name="Path">File path</param>
/// <returns>True if a folder</returns>
public bool IsFolder(string path)
{
return ((File.GetAttributes(path) & FileAttributes.Directory) == FileAttributes.Directory);
}
from http://www.jonasjohn.de/snippets/csharp/is-folder.htm
Ответ 6
Прочитайте атрибуты файла:
FileAttributes att = System.IO.File.GetAttributes(PATH_TO_FILE);
Проверьте флаг Directory.
Ответ 7
Учитывая, что конкретная строка пути не может представлять как каталог, так и файл, то следующее работает очень хорошо и открывает дверь для других операций.
bool isFile = new FileInfo(path).Exists;
bool isDir = new DirectoryInfo(path).Exists;
Если вы работаете с файловой системой, использование FileInfo
и DirectoryInfo
намного проще, чем использование строк.
Ответ 8
Хмм, похоже, что класс Files
(в java.nio
) действительно имеет статический метод isDirectory
. Итак, я думаю, вы могли бы использовать следующее:
Path what = ...
boolean isDir = Files.isDirectory(what);