如何尝试创建文件,并返回一个指示是否已创建的值?

Joe*_*nta 5 .net c# windows file-io .net-4.0

我正在寻找类似于这样的签名的东西:

static bool TryCreateFile(string path);
Run Code Online (Sandbox Code Playgroud)

这需要避免跨线程,进程甚至访问相同文件系统的其他机器的潜在竞争条件,而不要求当前用户拥有超出其所需的任何权限File.Create.目前,我有以下代码,我不是特别喜欢:

static bool TryCreateFile(string path)
{
    try
    {
        // If we were able to successfully create the file,
        // return true and close it.
        using (File.Open(path, FileMode.CreateNew))
        {
            return true;
        }
    }
    catch (IOException)
    {
        // We want to rethrow the exception if the File.Open call failed
        // for a reason other than that it already existed.
        if (!File.Exists(path))
        {
            throw;
        }
    }

    return false;
}
Run Code Online (Sandbox Code Playgroud)

还有另一种方法可以做到这一点,我错过了吗?

这适用于以下帮助器方法,旨在为目录创建"下一个"顺序空文件并返回其路径,再次避免跨线程,进程甚至访问同一文件系统的其他计算机的潜在竞争条件.所以我想一个有效的解决方案可能涉及到不同的方法:

static string GetNextFileName(string directoryPath)
{
    while (true)
    {
        IEnumerable<int?> fileNumbers = Directory.EnumerateFiles(directoryPath)
                                                 .Select(int.Parse)
                                                 .Cast<int?>();
        int nextNumber = (fileNumbers.Max() ?? 0) + 1;
        string fileName = Path.Combine(directoryPath, nextNumber.ToString());
        if (TryCreateFile(fileName))
        {
            return fileName;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Edit1:我们可以假设在执行此代码时不会从目录中删除文件.

Hen*_*man 3

不,没有直接的方法,也没有办法避免异常处理。

即使您尝试打开现有文件,例如

if (File.Exists(fName))
   var s = File.OpenRead(fname);
Run Code Online (Sandbox Code Playgroud)

您仍然可以获得各种异常,包括 FileNotFound。

这是因为您提到的所有原因:

跨线程、进程甚至其他机器

但您可能想看一下System.IO.Path.GetRandomFileName()。我认为他的 i 基于 WinAPI 函数,可以让你指定路径等。