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

如果它们都不存在,那么我就不去做任何一个分支,所以假设它们都存在。

50422 次浏览

您可以通过一些互操作代码来实现这一点:

    [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.GetAttritribute (字符串路径)的代码:

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

如您所见,它还调用非托管代码以检索文件属性,因此关于引入非托管代码是危险的参数是无效的。同样,关于完全保留在托管代码中的参数。不存在执行此操作的托管代码实现。甚至调用文件。正如其他答案所建议的那样,GetAttritribute ()在调用非托管代码方面存在相同的“问题”,我相信这是确定路径是否为目录的更可靠方法。

编辑 回复@Christian K 关于 CAS 的评论。我相信 GetAttritribute 提出安全性要求的唯一原因是因为它需要读取文件的属性,所以它希望确保调用代码具有这样做的权限。这与底层操作系统检查不同(如果有的话)。您总是可以在对 PathisDirectory 的 P/Invoke 调用周围创建一个包装函式,如果需要的话,这个调用还需要特定的 CAS 权限。

用途:

System.IO.File.GetAttributes(string path)

并检查返回的 FileAttributes结果是否包含值 FileAttributes.Directory:

bool isDir = (File.GetAttributes(path) & FileAttributes.Directory)
== FileAttributes.Directory;

假设目录存在..。

bool isDir = (File.GetAttributes(path) & FileAttributes.Directory)
== FileAttributes.Directory;

看看这个:

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

阅读文件属性:

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

检查 目录标志。

假设一个特定的路径字符串不能同时表示一个目录 还有和一个文件,那么以下操作就可以正常工作,并为其他操作打开大门。

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

如果使用的是文件系统,那么使用 FileInfoDirectoryInfo比使用字符串简单得多。

我认为这是最简单的方法,你只需要两张支票:

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
}

嗯,看起来 Files类(在 java.nio中)实际上有一个静态 isDirectory方法。所以,我觉得你可以用下面的方法:

Path what = ...
boolean isDir = Files.isDirectory(what);