我正在处理目录和文件的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方法来处理这个问题,但我还没有能够这样做。是否存在这样的方法,如果不存在,确定路径是文件还是目录的最直接的方法是什么?


当前回答

我明白了,我迟到了10年。 我面临的情况是,从某些属性中,我可以接收文件名或完整的文件路径。如果没有提供路径,我必须通过附加由另一个属性提供的“全局”目录路径来检查文件的存在性。

对我来说

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

成功了。 好吧,这不是魔法,但也许这可以为某人节省几分钟的思考时间。 因为这只是一个字符串解析,所以带点的diri -names可能会给出假阳性…

其他回答

使用这篇文章中所选的答案,我看了评论并给予了信任 @Ş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;
    }
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));
          }
     }
}

下面是我们使用的:

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

  }

}

在结合其他答案的建议后,我意识到我得到了和罗尼·奥弗比的答案差不多的东西。以下是一些测试,指出一些需要考虑的问题:

文件夹可以有扩展名:C:\Temp\folder_with.dot 文件不能以目录分隔符(斜杠)结束 从技术上讲,有两个特定于平台的目录分隔符——也就是说,可能是斜杠,也可能不是。和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)
{
    // https://stackoverflow.com/questions/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;
}

也许是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;
    }