.NET Как проверить, является ли путь файлом, а не каталогом? - PullRequest
72 голосов
/ 13 января 2009

У меня есть путь, и мне нужно определить, является ли он каталогом или файлом.

Это лучший способ определить, является ли путь файлом?

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

Если обоих не существует, то я не пойду делать ни одну ветку. Итак, предположим, что они оба существуют.

Ответы [ 8 ]

109 голосов
/ 13 января 2009

Использование:

System.IO.File.GetAttributes(string path)

и проверьте, содержит ли возвращенный результат FileAttributes значение FileAttributes.Directory:

bool isDir = (File.GetAttributes(path) & FileAttributes.Directory)
                 == FileAttributes.Directory;
53 голосов
/ 13 января 2009

Я думаю, что это самый простой способ, когда вам нужно только две проверки:

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
}
10 голосов
/ 13 января 2009

Вы можете сделать это с помощью некоторого кода взаимодействия:

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

Для дальнейшего уточнения некоторых комментариев ...

Внедрение неуправляемого кода в это не более опасно, чем любые другие вызовы файлов или операций ввода-вывода в .NET, так как они в конечном итоге все вызывают неуправляемый код.

Это единственный вызов функции с использованием строки. Вы не вводите новые типы данных и / или использование памяти, вызывая эту функцию. Да, вам нужно полагаться на неуправляемый код для правильной очистки, но в конечном итоге вы зависите от большинства вызовов, связанных с вводом / выводом.

Для справки, вот код 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.

7 голосов
/ 13 января 2009

Предполагая, что каталог существует ...

bool isDir = (File.GetAttributes(path) & FileAttributes.Directory)
                  == FileAttributes.Directory;
3 голосов
/ 13 января 2009

Проверьте это:

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

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

2 голосов
/ 13 января 2009

Чтение атрибутов файла:

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

Проверьте наличие флага Directory .

1 голос
/ 13 января 2009

Учитывая, что конкретная строка пути не может представлять как каталог , так и файл, то следующее прекрасно работает и открывает двери для других операций.

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

Если вы работаете с файловой системой, использовать FileInfo и DirectoryInfo намного проще, чем использовать строки.

0 голосов
/ 11 января 2013

Хм, похоже, класс Filesjava.nio) на самом деле имеет статический метод isDirectory. Итак, я думаю, вы могли бы использовать следующее:

Path what = ...
boolean isDir = Files.isDirectory(what);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...