检查path是文件还是目录的更好方法?

我正在处理目录和文件的TreeView 。 用户可以select一个文件或一个目录,然后做一些事情。 这要求我有一个方法,根据用户的select执行不同的操作。

目前我正在做这样的事情来确定path是文件还是目录:

 bool bIsFile = false; bool bIsDirectory = false; try { string[] subfolders = Directory.GetDirectories(strFilePath); bIsDirectory = true; bIsFile = false; } catch(System.IO.IOException) { bIsFolder = false; bIsFile = true; } 

我不禁感到有更好的方法来做到这一点! 我希望find一个标准的.NET方法来处理这个问题,但是我一直没能做到。 这样的方法是否存在,如果不存在,那么确定path是文件还是目录的最直接方法是什么?

从如何判断path是文件还是目录 :

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

如何使用这些?

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

只有这一行,你可以得到如果一个path是一个目录或文件:

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

最准确的方法是使用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); } 

作为Directory.Exists()的替代方法,可以使用File.GetAttributes()方法来获取文件或目录的属性,以便可以创build一个像下面这样的帮助方法:

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

填充包含该项目的其他元数据的控件时,也可以考虑将对象添加到TreeView控件的标签属性中。 例如,您可以为文件添加FileInfo对象,为目录添加DirectoryInfo对象,然后在标签属性中testing项目types,以便在点击项目时保存额外的系统调用以获取该数据。

考虑到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; } } 

以下是它如何testing:

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

这是我的:

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

这与其他人的答案类似,但不完全相同。

当遇到类似的问题时,我遇到了这个问题,除了我需要检查一个文件或文件夹的path是否可能实际不存在时 。 上面的答案有几条评论提到他们不适合这种情况。 我find了一个解决scheme(我使用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 

希望这可以帮助一个人!

所以在我知道的游戏后期,但是我认为我会分享这个。 如果你只是把path当作string来工作,搞清楚这一点很简单:

 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) 

请记住,这只适用于path本身,而不是path和“物理磁盘”之间的关系…所以它不能告诉你path/文件是否存在或类似的东西,但它确定可以告诉你,如果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; } } } 

我使用以下内容,它也testing扩展,这意味着它可以用于testing,如果提供的path是一个文件,但不存在的文件。

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

如果你想查找目录,包括那些标记为“隐藏”和“系统”的目录,试试这个(需要.NET V4):

 FileAttributes fa = File.GetAttributes(path); if(fa.HasFlag(FileAttributes.Directory)) 
 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)); } } } 

我需要这个,post帮助,这将它归结为一行,如果path根本不是一个path,它只是返回并退出该方法。 它解决了所有上述问题,也不需要结尾的斜线。

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

在这篇文章中使用select的答案,我看了评论,并给予@ŞafakGür,@Anthony和@Quinn Wilson的信任他们的信息位,使我得到了这个改进的答案,我写和testing:

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

结合其他答案的build议后,我意识到我提出了与罗尼·奥弗比的回答大致相同的东西。 下面是一些testing,指出一些事情要考虑:

  1. 文件夹可以有“扩展名”: C:\Temp\folder_with.dot
  2. 文件不能以目录分隔符(斜杠)结尾
  3. 技术上有两个目录分隔符是平台特定的 – 即可能或不可以是斜线( Path.DirectorySeparatorCharPath.AltDirectorySeparatorChar

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

这不会工作吗?

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

这是使用DirectoryInfo获取属性

 Dim newnode As TreeNode Dim dirs As New DirectoryInfo(node.FullPath) For Each dir As DirectoryInfo In dirs.GetDirectories() If dir.Attributes = FileAttributes.Directory Then Else End If Next 

这将工作,如果你试图通过DirectoryInfo试图创build一个TreeView或阅读一个TreeView