78

我有一个路径,我需要确定它是目录还是文件。

这是确定路径是否为文件的最佳方法吗?

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

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

4

8 回答 8

122

采用:

System.IO.File.GetAttributes(string path)

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

bool isDir = (File.GetAttributes(path) & FileAttributes.Directory)
                 == FileAttributes.Directory;
于 2009-01-13T15:52:09.947 回答
57

我认为这是最简单的方法,您只需要两次检查:

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
}
于 2009-01-13T16:00:14.547 回答
11

您可以使用一些互操作代码来做到这一点:

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

为了进一步澄清一些评论......

在此引入非托管代码并不比 .NET 中的任何其他文件或 I/O 相关调用更危险,因为它们最终都调用非托管代码。

这是使用字符串的单个函数调用。通过调用此函数,您不会引入任何新的数据类型和/或内存使用。是的,您确实需要依赖非托管代码来正确清理,但您最终对大多数 I/O 相关调用都有依赖。

作为参考,这里是来自 Reflector 的 File.GetAttributes(string path) 的代码:

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 提出安全要求的唯一原因是因为它需要读取文件的属性,因此它希望确保调用代码具有这样做的权限。这与底层操作系统检查(如果有的话)不同。如有必要,您始终可以围绕对 PathIsDirectory 的 P/Invoke 调用创建一个包装函数,该函数还需要某些 CAS 权限。

于 2009-01-13T15:50:57.297 回答
7

假设目录存在...

bool isDir = (File.GetAttributes(path) & FileAttributes.Directory)
                  == FileAttributes.Directory;
于 2009-01-13T15:52:32.003 回答
4

看一下这个:

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

于 2009-01-13T15:54:05.370 回答
2

读取文件属性:

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

检查目录标志。

于 2009-01-13T15:54:42.157 回答
1

鉴于一个特定的路径字符串不能同时表示一个目录一个文件,那么下面的工作就很好,并为其他操作打开了大门。

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

如果您正在使用文件系统,则使用FileInfoandDirectoryInfo比使用字符串要简单得多。

于 2009-01-13T15:55:43.400 回答
-4

嗯,看起来Files类(in java.nio)实际上有一个静态isDirectory方法。所以,我认为你实际上可以使用以下内容:

Path what = ...
boolean isDir = Files.isDirectory(what);
于 2013-01-10T20:20:37.050 回答