检查文件/目录是否存在:有没有更好的方法?

我发现自己做了很多,只是为了确保文件名不被使用。 有没有更好的办法?

Directory.Exists(name) || File.Exists(name) 

当然:)

 internal static bool FileOrDirectoryExists(string name) { return (Directory.Exists(name) || File.Exists(name)); } 

请注意,您正在使用Exists()来检查正在使用的文件或目录名称的事实将受到竞争条件的限制。

例如,在Exists()testing通过之后的任何时候,在您的代码达到您创build文件的位置之前,可能会创build一个具有该名称的文件。

(我假设这是该文件已经存在的特殊条件)。

简单地打开文件,指定一个合适的FileShare参数更可靠。

例:

 using System; using System.IO; static class FileNameInUse { static void Main(string[] args) { string path = args[0]; using (var stream = File.Open(path, FileMode.CreateNew, FileAccess.Write, FileShare.None)) { // Write to file } } } 

所以简单地处理IOExceptionexception可能会导致简单的代码不太容易出现竞争状况,因为现在:

  • 如果其他东西已经创build了这个文件, FileMode.CreateNew将会抛出一个IOExceptionexception
  • 如果您打开并创build成功,由于FileShare.None ,没有其他进程可以访问该文件,直到您closures它。

不幸的是,不可能检查一个文件是否正在被使用 ,并且不会抛出exception,没有一些丑陋的P / Invoke:

  bool IsFileInUse(string fileName) { IntPtr hFile = Win32.CreateFile(fileName, Win32.FILE_READ_DATA, 0, IntPtr.Zero, Win32.OPEN_EXISTING, Win32.FILE_ATTRIBUTE_NORMAL, IntPtr.Zero); if (hFile.ToInt32() == Win32.INVALID_HANDLE_VALUE) return true; Win32.CloseHandle(hFile); return false; } class Win32 { const uint FILE_READ_DATA = 0x0001; const uint FILE_SHARE_NONE = 0x00000000; const uint FILE_ATTRIBUTE_NORMAL = 0x00000080; const uint OPEN_EXISTING = 3; const int INVALID_HANDLE_VALUE = -1; [DllImport("kernel32.dll", SetLastError=true)] internal static extern IntPtr CreateFile(string lpFileName, uint dwDesiredAccess, uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile); [DllImport("kernel32.dll")] internal static extern bool CloseHandle(IntPtr hObject); } 

而且这个快速检查也容易出现竞争条件,除非你从它返回文件句柄,并将其传递给相关的FileStream构造函数。

另一种检查文件是否存在的方法。

 FileInfo file = new FileInfo("file.txt"); if (file.Exists) { // TO DO } 

我认为这是唯一的方法。 我通常有一个“FileManager”类,它有静态方法封装I / O方法,包括您指定的方法,然后在所有应用程序中使用该“FileManager”作为库。

我的方式来检查这是使用FileSystemInfo ,这是我的代码:

 FileSystemInfo info = File.GetAttributes(data.Path).HasFlag(FileAttributes.Directory) ? new DirectoryInfo(data.Path) : (FileSystemInfo)new FileInfo(data.Path); return info.Exists;