2009-01-13 156 views
66

我有一个路径,我需要确定它是否是一个目录或文件。.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); 

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

+0

http://stackoverflow.com/a/17198139/128506 – HAL9000 2014-06-29 22:30:03

+0

的可能的复制(http://stackoverflow.com/questions/1395205/better-way-to-check-if-a-path-is-a-file-or-a-directory) – DavidRR 2016-09-07 12:50:54

回答

101

用途:

System.IO.File.GetAttributes(string path) 

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

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

你可以用一些互操作的代码做到这一点:

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

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

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

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

仅供参考,这里是从反射器的代码File.GetAttributes(字符串路径):

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()作为其他答案建议有调用unmanged代码相同的“问题”,我相信这是更可靠的方法来完成确定路径是否是一个目录。

编辑要回答@Christian K关于CAS的评论。我相信GetAttributes唯一的原因使安全需求是因为它需要读取文件的属性,所以它想确保调用代码有权这样做。这与底层的操作系统检查不一样(如果有的话)。如果需要,您可以始终围绕对PathIsDirectory的P/Invoke调用创建一个包装函数,该函数也需要某些CAS权限。

+2

这似乎是分配工作,以找出是否路径是文件或目录。 – 2009-01-13 15:54:07

+0

那是多么的工作?你声明一个单一的导入函数,然后可以调用它,就好像它是一个本地方法。 – 2009-01-13 15:58:21

+2

我不明白为什么这是downvoted,但只保留使用.NET功能的托管代码会简单得多。 – 2009-01-13 16:10:31

7

假设目录存在...

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

检查了这一点:

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

2

阅读文件属性:

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

检查的目录标志。

1

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

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

如果你使用的文件系统的工作,使用FileInfoDirectoryInfo比使用字符串要简单得多。

45

我觉得这是你只需要两个检查最简单的方法:

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

嗯,它看起来像Files类(在java.nio)实际上有一个静态isDirectory方法。所以,我觉得你实际上可以使用以下:?更好的方法来检查,如果路径是一个文件或目录]

Path what = ... 
boolean isDir = Files.isDirectory(what); 
相关问题