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

时间:2010-04-03 10:22:41

标签: c# .net file

我发现自己这么做只是为了确保文件名不被使用。还有更好的方法吗?

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

8 个答案:

答案 0 :(得分:56)

当然:)

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

答案 1 :(得分:33)

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

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

(我假设文件已存在是一个例外情况)。

简单地打开文件,指定适当的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
        }
    }
}

因此,在失败时简单地处理 IOException 可能会导致更简单的代码更不容易出现竞争条件,因为现在:

  • 如果其他内容已经创建了该文件,FileMode.CreateNew将导致IOException被抛出
  • 如果由于FileShare.None而打开并创建成功,则在关闭文件之前,其他任何进程都无法访问该文件。

不幸的是,无法检查某个文件当前是否正在正在使用,并且在没有一些丑陋的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构造函数。

答案 2 :(得分:4)

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

答案 3 :(得分:2)

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

FileInfo file = new FileInfo("file.txt");

if (file.Exists)
{
    // TO DO
}

答案 4 :(得分:2)

我检查这个的方法是使用FileSystemInfo,这是我的代码:

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

return info.Exists;

答案 5 :(得分:0)

您可以使用以下功能:

[DllImport("shlwapi", EntryPoint = "PathFileExists", CharSet = CharSet.Unicode)]
public static extern bool PathExists(string path);

答案 6 :(得分:0)

如何检查FileAttributes == -1?

public static bool PathExists(this string path) {
    DirectoryInfo dirInfo = null;
    try { dirInfo = new DirectoryInfo(path.TrimEnd(Path.DirectorySeparatorChar)); }
    catch { }
    if (dirInfo == null || dirInfo.Attributes == (FileAttributes)(-1))
        return false;
    return true;
}

答案 7 :(得分:-2)

bool FileOrDirectoryExists(string path)
{
    try
    {
        File.GetAttributes(_source);
    }
    catch (FileNotFoundException)
    {
        return false;
    }
    return true;
}