我有一个路径,我需要确定它是一个目录或文件.
这是确定路径是否为文件的最佳方法吗?
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);
如果两者都不存在那么我就不会去任何一个分支.所以假设它们都存在.
使用:
System.IO.File.GetAttributes(string path)
并检查返回的FileAttributes
结果是否包含值FileAttributes.Directory
:
bool isDir = (File.GetAttributes(path) & FileAttributes.Directory) == FileAttributes.Directory;
我认为这是您只需要两次检查的最简单方法:
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 }
您可以使用一些互操作代码执行此操作:
[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(字符串路径)的代码:
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权限.
假设目录存在...
bool isDir = (File.GetAttributes(path) & FileAttributes.Directory) == FileAttributes.Directory;