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


383

Я обрабатываю TreeViewкаталоги и файлы. Пользователь может выбрать файл или каталог, а затем что-то сделать с ним. Это требует от меня наличия метода, который выполняет различные действия в зависимости от выбора пользователя.

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

bool bIsFile = false;
bool bIsDirectory = false;

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

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

Я не могу не чувствовать, что есть лучший способ сделать это! Я надеялся найти стандартный метод .NET, чтобы справиться с этим, но я не смог этого сделать. Существует ли такой метод, и если нет, то какой самый простой способ определить, является ли путь файлом или каталогом?


8
Может кто-нибудь отредактировать заголовок вопроса, чтобы указать «существующий» файл / каталог? Все ответы относятся к пути к файлу / каталогу, который находится на диске.
Джейк Бергер

1
@jberger, пожалуйста, обратитесь к моему ответу ниже. Я нашел способ сделать это для путей к файлам / папкам, которые могут существовать или не существовать.
lhan


Как вы заполняете это дерево? Как вы получаете путь из этого?
Random832

Ответы:


596

От Как сказать , если путь файла или каталога :

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

Обновление для .NET 4.0+

Согласно комментариям ниже, если вы используете .NET 4.0 или более позднюю версию (и максимальная производительность не критична), вы можете написать код более понятным способом:

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

8
+1 Это лучший подход и он значительно быстрее предложенного мною решения.
Эндрю Хэйр

6
@ KeyMs92 Это побитовая математика. По сути, attr - это некоторое двоичное значение с одним битом, означающим «это каталог». Побитовый &оператор и вернет двоичное значение, в котором включены только те биты, которые включены (1) в обоих операндах. В этом случае выполнение поразрядно и операция против, attrи FileAttributes.Directoryзначение вернет значение, FileAttributes.Directoryесли бит атрибута файла каталога включен. Смотрите en.wikipedia.org/wiki/Bitwise_operation для лучшего объяснения.
Кайл Трауберман

6
@jberger Если путь не существует, то неоднозначно, C:\Tempотносится ли к каталогу с именем Tempили к файлу Temp. Что должен делать код?
ta.speot.is

26
@Key: после .NET 4.0, attr.HasFlag(FileAttributes.Directory)можно использовать вместо.
Шафак Гюр

13
@ ŞafakGür: Не делайте этого внутри чувствительного ко времени цикла. attr.HasFlag () работает медленно и использует Reflection для каждого вызова
springy76

247

Как насчет использования этих?

File.Exists();
Directory.Exists();

43
Это также имеет то преимущество, что, в отличие от этого, не выдает исключение на неверный путь File.GetAttributes().
Дина

В моем проекте я использую библиотеку Long Path из BCL bcl.codeplex.com/…, поэтому нет возможности получить атрибуты файла, но вызов Exist - хороший обходной путь.
Puterdo Borato

4
@jberger Я бы ожидал, что он не будет работать для путей к несуществующим файлам / папкам. File.Exists ("c: \\ temp \\ nonexistant.txt") должен возвращать false, как это происходит.
michaelkoss

12
Если вы беспокоитесь о несуществующих файлах / папках, попробуйте это 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 }
Дастин Таунсенд

1
Более подробную информацию об этом можно найти по адресу msdn.microsoft.com/en-us/library/… ..
Моджи

20

Только с этой строкой вы можете получить, если путь является каталогом или файлом:

File.GetAttributes(data.Path).HasFlag(FileAttributes.Directory)

4
Имейте в виду, что для этого нужен как минимум .NET 4.0. Также это будет взрываться, если путь не является допустимым путем.
Nawfal

Используйте объект FileInfo, чтобы проверить, существует ли путь: FileInfo pFinfo = new FileInfo (FList [0]); if (pFinfo.Exists) {if (File.GetAttributes (FList [0]). HasFlag (FileAttributes.Directory)) {}}. Этот работает для меня.
Майкл Стимсон

Если вы уже создали объект FileInfo и используете свойство Exists экземпляра, почему бы не получить доступ к его свойству Attributes вместо использования статического метода File.GetAttributes ()?
Динамический Май

10

Вот мой:

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

Это похоже на ответы других, но не совсем то же самое.


3
Технически вы должны использовать Path.DirectorySeparatorCharиPath.AltDirectorySeparatorChar
drzaus

1
Эта идея угадать намерения интересна. ИМХО лучше разделить на два метода. Метод Один делает тесты Существования, возвращая обнуляемое логическое значение. Если вызывающая сторона тогда хочет получить часть «угадай» с нулевым результатом от «Один», тогда вызови метод «Два», который делает угадайку.
ToolmakerSteve

2
Я бы переписал это, чтобы вернуть кортеж с тем, угадал он или нет.
Ронни Оверби

1
«если имеет расширение, то это файл» - это не так. Файл не должен иметь расширение (даже в Windows), а каталог может иметь «расширение». Например, это может быть файл или каталог: «C: \ New folder.log»
bytedev

2
@bytedev Я знаю это, но в этой точке кода код угадывает намерение. Есть даже комментарий, говорящий так. Большинство файлов имеют расширение. Большинство каталогов этого не делают.
Ронни Оверби

7

В качестве альтернативы Directory.Exists () вы можете использовать метод File.GetAttributes (), чтобы получить атрибуты файла или каталога, чтобы вы могли создать вспомогательный метод, подобный этому:

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

Вы также можете рассмотреть возможность добавления объекта в свойство тега элемента управления TreeView при заполнении элемента управления, который содержит дополнительные метаданные для элемента. Например, вы можете добавить объект FileInfo для файлов и объект DirectoryInfo для каталогов, а затем проверить тип элемента в свойстве тега, чтобы сохранить выполнение дополнительных системных вызовов для получения этих данных при нажатии на элемент.


2
чем это отличается от другого ответа
Джейк Бергер

6
Вместо этого ужасного блока логики, попробуйтеisDirectory = (fa & FileAttributes.Directory) != 0);
Immortal Blue

5

Это было лучшее, что я мог придумать, учитывая поведение свойств Exists и 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;
    }
}

Вот как это проверяется:

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

5

После объединения предложений из других ответов я понял, что придумал то же самое, что и ответ Ронни Оверби . Вот несколько тестов, на которые следует обратить внимание:

  1. папки могут иметь «расширения»: C:\Temp\folder_with.dot
  2. файлы не могут заканчиваться разделителем каталогов (косая черта)
  3. Технически существует два разделителя каталогов, которые зависят от платформы - то есть могут быть или не быть косыми чертами ( Path.DirectorySeparatorCharи Path.AltDirectorySeparatorChar)

Тесты (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);
}

Результаты

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 

метод

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

Path.DirectorySeparatorChar.ToString()вместо строки с ""?
Ушел кодирование

@GoneCoding возможно; в то время я работал со множеством обнуляемых свойств, поэтому я привык «конкатать с пустой строкой», а не беспокоиться о проверке на ноль. Вы также можете делать new String(Path.DirectorySeparatorChar, 1)то, что ToStringделает, если хотите действительно оптимизироваться.
drzaus

4

Наиболее точным подходом будет использование некоторого кода взаимодействия из 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);

Затем вы бы назвали это так:

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

31
Некрасиво. Я ненавижу взаимодействие, чтобы делать эти простые задачи. И это не портативно. и это безобразно Я говорил, что это некрасиво? :)
Игнасио Солер Гарсия

5
@SoMoS Это может быть "некрасиво" по вашему мнению, но это все еще самый точный подход. Да, это не портативное решение, но вопрос был не в этом.
Скотт Дорман

8
Что вы имеете в виду именно под точным? Он дает те же результаты, что и ответ Куинн Уилсон, и требует взаимодействия, которое нарушает мобильность. Для меня это так же точно, как другие решения и побочные эффекты, которые другие не делают.
Игнасио Солер Гарсия

7
Для этого есть Framework API. Использование Interop - не лучший способ.
TomXP411

5
Да, это работает, но это не «самое точное» решение - не более, чем использование существующего .NET Framework. Вместо этого вы берете 6 строк кода, чтобы заменить то, что можно сделать в одной строке, на .NET Framework, и привязываетесь только к использованию Windows, а не оставляете открытой возможность переносить это с Mono Project. Никогда не используйте Interop, когда .NET Framework предлагает более элегантное решение.
Расс

2

Вот что мы используем:

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

  }

}

2

Я сталкивался с этим, когда сталкивался с подобной проблемой, за исключением того, что мне нужно было проверить, существует ли путь для файла или папки, когда этот файл или папка могут фактически не существовать . Было несколько комментариев к ответам выше, в которых упоминалось, что они не будут работать для этого сценария. Я нашел решение (я использую VB.NET, но вы можете конвертировать, если вам нужно), которое, кажется, хорошо работает для меня:

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

Надеюсь, это может быть полезно для кого-то!


1
Вы пробовали метод Path.HasExtension ?
Джейк Бергер

Если он не существует, то это не файл или каталог. Любое имя может быть создано как либо. Если вы намереваетесь создать его, то вы должны знать, что вы создаете, а если нет, то зачем вам эта информация?
Random832

8
Папка может быть названа, test.txtи файл может быть назван test- в этих случаях ваш код будет давать неправильные результаты
Стефан Бауэр

2
В классах System.IO.FIle и System.IO.Directory есть метод .Exists. это то, что нужно сделать. Каталоги могут иметь расширения; Я вижу это часто.
TomXP411

2

тааак поздно в игре, я знаю, но думал, что поделюсь этим в любом случае. Если вы работаете исключительно с путями в виде строк, понять это легко, как пирог:

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

например: ThePath == "C:\SomeFolder\File1.txt"будет в конечном итоге это:

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

Другой пример: ThePath == "C:\SomeFolder\"в конечном итоге это будет так:

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

И это также будет работать без обратной косой черты: ThePath == "C:\SomeFolder"в конечном итоге это будет так:

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

Имейте в виду, что это работает только с самими путями, а не с отношением между путем и «физическим диском» ... поэтому он не может сказать вам, существует ли путь / файл или что-то в этом роде, но он уверен может сказать вам, если путь является папкой или файлом ...


2
Не работает, System.IO.FileSystemWatcherпоскольку, когда каталог удаляется, он отправляет c:\my_directoryв качестве аргумента тот же аргумент, что и при c:\my_directoryудалении файла без расширения .
Рэй Ченг

GetDirectoryName('C:\SomeFolder')возвращается 'C:\', так что ваш последний случай не работает. Это не делает различий между каталогами и файлами без расширений.
Люси

Вы ошибочно полагаете, что путь к каталогу всегда будет включать в себя конечный «\». Например, Path.GetDirectoryName("C:\SomeFolder\SomeSubFolder")вернется C:\SomeFolder. Обратите внимание, что ваши собственные примеры того, что возвращает GetDirectoryName, показывают, что он возвращает путь, который не заканчивается обратной косой чертой. Это означает, что если кто-то использует GetDirectoryName в другом месте для получения пути к каталогу, а затем передает его в ваш метод, он получит неправильный ответ.
ToolmakerSteve

1

Если вы хотите найти каталоги, в том числе помеченные как «скрытые» и «системные», попробуйте это (требуется .NET V4):

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

1

Мне это нужно, посты помогли, это сводит их к одной строке, и если путь вообще не путь, он просто возвращает и выходит из метода. Он решает все вышеперечисленные проблемы, также не нуждается в конце.

if (!Directory.Exists(@"C:\folderName")) return;

0

Я использую следующее, оно также проверяет расширение, которое означает, что его можно использовать для проверки, если указанный путь - это файл, но файл, который не существует.

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

1
Расширение FileInfo (IMAO) является хорошим вариантом для проверки несуществующих путей
dataCore

2
Ваше второе состояние (другое) вонючий. если это не существующий файл, то вы не знаете, что это может быть (каталоги могут заканчиваться чем-то вроде ".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));
          }
     }
}

0

Используя выбранный ответ в этом посте, я посмотрел комментарии и доверился @ ŞafakGür, @Anthony и @Quinn Wilson за их информационные биты, которые привели меня к этому улучшенному ответу, который я написал и протестировал:

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

Кажется немного расточительным, чтобы проверить атрибуты после того, как уже проверил наличие Directory / File Exists ()? Эти два звонка делают всю работу, необходимую здесь.
Ушел кодирование

0

Может быть для 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;
    }

0

Я вижу, я на 10 лет опоздал на вечеринку. Я столкнулся с ситуацией, когда из какого-то свойства я могу получить либо имя файла, либо полный путь к файлу. Если путь не указан, я должен проверить существование файла, прикрепив «глобальный» путь к каталогу, предоставленный другим свойством.

В моем случае

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

сделал свое дело. Ладно, это не волшебство, но, возможно, это может сэкономить кому-то несколько минут на выяснение. Так как это просто разбор строк, Dir-имена с точками могут давать ложные срабатывания ...


0

Здесь очень поздно, но я обнаружил, что Nullable<Boolean>возвращаемое значение довольно уродливо - IsDirectory(string path)возвращение nullне равнозначно несуществующему пути без подробного комментирования, поэтому я придумал следующее:

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

Этот вспомогательный метод написан, чтобы быть многословным и достаточно кратким, чтобы понять намерение при первом прочтении.

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

-4

Разве это не сработает?

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

1
Это не сработает только потому, что в именах папок могут быть точки
KSib

Также у файлов не должно быть периодов в них.
Кит Пинсон
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.