【问题标题】:How to Prevent Deletion of a Locked File in C#如何防止在 C# 中删除锁定的文件
【发布时间】:2017-06-13 09:23:07
【问题描述】:

如何防止从当前处于打开状态的解决方案的 AppDomain.CurrentDomain 中创建的临时文件夹中删除文件.. 我只想删除未使用的文件.. 我试过这个..

public void TempDocumentDeletion()
 {
   string curUserFolder = AppDomain.CurrentDomain.GetData("DataDirectory") + "\\temp" + "\\" + CurrentUserData.UserId;
   DirectoryInfo curdir = new System.IO.DirectoryInfo(curUserFolder);

        foreach (FileInfo files in curdir.GetFiles())
        {
            var fullName = files.FullName;
            if (!IsFileLocked(fullName))
            {

                files.Delete();

            }

 }

 public static bool IsFileLocked(string filePath)
    {
        var file = new FileInfo(filePath);
        FileStream stream = null;
        try
        {                
          stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None);
        }
        catch (IOException)
        {
            //the file is unavailable because it is:
            //  still being written to or being processed by another thread
            return true;
        }
        finally
        {
            if (stream != null)
                stream.Close();
        }

        // file is not locked
        return false;
}

但有时,使用过的文件也会被删除...有没有其他方法可以解决它...或者需要进行任何修改。

【问题讨论】:

  • 它在哪里被删除了?是否所有线程都在修改您的应用程序中的文件?
  • 那是...不是javascript;您能否更具体地了解允许删除正在使用的文件的场景?并且您确定它当时实际上是打开的,而不是“我已经从中读取了我想要的内容,关闭了文件对象,但预计它仍会被锁定”?因为问题中显示的代码只会在最短暂的瞬间被锁定
  • 或者您是说要提前检查一个文件是否可以被删除?这听起来是个好主意,但最终只会创建一个竞争条件 - 当你认为你可以删除它时,你必须处理这种情况,尝试删除它,然后失败(通过异常)

标签: c# file file-locking


【解决方案1】:

按照我的解释,问题本质上是:

如何检查文件是否被锁定,意思是:我不应该尝试删除它

所以问题中的方法将用作:

if(!IsFileLocked(path))
    File.Delete(path);

问题是:你马上就有了竞争条件。在IsFileLocked 检查和File.Delete 之间,事情可能会发生变化(在任一方向)。这些更改可能与您的应用程序相关,也可能不相关(可能是另一个进程锁定了文件)。

所以:在一般情况下:你不能。您需要预期 File.Delete 可能会失败,并适当地处理异常。在最基本的层面上:

try {
    File.Delete(path);
} catch (Exception ex) {
    Log($"could not delete file {path}: {ex.Message}");
}

(显然,如果您可以改进这种处理方式:太好了)

如果你只是偶尔做文件工作,老实说:这可能是离开它的方法,因为你需要那个代码无论如何,它可以解决你遇到的每一个问题.

如果您执行大量文件 IO,您可能需要考虑使用内存中的文件注册表来跟踪 您的代码 已打开的文件对象,以便您知道不要尝试删除哪些文件对象.这本身就有很多线程问题,而且不是微不足道的,并且它无法帮助其他进程接触文件,所以你仍然需要“期望File.Delete失败”的处理。但您也可以让文件注册表本身在消费代码完成后负责删除文件。

【讨论】:

    猜你喜欢
    • 2023-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-28
    • 1970-01-01
    • 2013-06-05
    • 2021-06-25
    • 2013-08-17
    相关资源
    最近更新 更多