为什么我不能在删除后创建一个txt文件?

本文关键字:一个 txt 文件 不能 删除 创建 为什么 | 更新日期: 2023-09-27 18:18:58

我的程序在启动时创建一个日志文件。用户可以通过设置选项来"清除日志",这将调用一个方法来删除日志文件。

        //calls for a YesNo prompt to delete log or not
        result = objectMessageBox.ReturnDeleteLogPrompt();
        if (result == DialogResult.Yes)
        {
            //throw prompt
            if (File.Exists(objectLog.GetLogLocation()) == true)
            {
                try
                {                        
                    //delete the log file
                    File.Delete(objectLog.GetLogLocation());                        
                    //throw balloon tip saying log was cleared
                    ShowBalloonTip("LogCleared");
                }
                catch (Exception ee)
                {
                    MessageBox.Show("Error thrown deleting log: " + ee);
                    System.Windows.Forms.Clipboard.SetText(ee.ToString());
                }
            }
        }

因为我已经完全删除了日志文件,所以我需要重新创建它。所以我调用了这样一个方法:

try
        {
            //we create a new log file so it seems that the log has just been cleared
            objectLog.CreateLog();
        }
        catch (Exception ee)
        {
            MessageBox.Show("Error occured while clearing log:'n" + ee);
        }

但是当它试图重新创建日志文件时,它抛出一个错误,上面写着:

"先。IOException:进程不能访问文件'~~',因为它正在被另一个进程使用。"

所以似乎在我删除文件的过程中,它一直在访问它?当我调用file.delete时,我需要处理一些东西吗?

为什么我不能在删除后创建一个txt文件?

我不知道细节,但是有很多原因可以解释为什么文件名在删除现有文件后不能立即用于重建:

  • 操作系统仍在等待删除操作
  • 防病毒程序或类似的安全功能在文件被删除时打开该文件,用于删除前分析
  • 一个防病毒程序或类似的安全功能已经打开了文件,而您正在使用它,并仍在响应您的删除请求

Mercurial在Windows上也有这个问题。如果您执行了一个锁定存储库的命令(这是使用临时文件完成的),然后立即执行了另一个需要锁定或至少确保没有锁定的命令,那么它可能会失败,并出现相同类型的错误,即文件正在使用,即使这是两个不同的进程,并且第一个进程已经退出。

换句话说,时间轴如下:

  • hg.exe实例#1启动,通过创建临时文件
  • 锁定仓库
  • hg.exe做它需要做的事情
  • hg.exe删除文件,然后退出
  • hg.exe实例#2启动,试图锁定存储库,失败,因为文件正在使用

他们的"修复"方法是简单地随机选择一个目录中未使用的文件名,将文件重命名为该名称,然后删除它。这并不能解决文件停留一段时间的问题,但它确实释放了文件名,并使其可以立即用于新文件。

已经有了一个公认的答案,但也许有人觉得这很有用(或者如果我又错过了一些明显的东西而浪费了我的时间,就会嘲笑它)

我的印象是File.Delete要么删除文件然后返回,要么抛出异常——直到我读到这个线程。

windows API提到,通过调用DeleteFile,文件被"标记为关闭删除",因为它允许在打开的文件上调用删除。在文件被标记为删除后,打开它的尝试将失败,显示为"拒绝访问"。当这个文件的最后一个句柄被关闭时,这个文件实际上被删除了。

如果windows在从最后一次对文件的CloseHandle调用返回之前实际上删除了该文件,理论上这段代码将保证该文件在using块以下被删除:

using (File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Delete))
{
    File.Delete(path);
}

如果另一个进程当前打开了该文件,File.Open将失败。

注意这里的区别,即使文件不存在(除非目录不存在),File.Delete也会成功。

与其删除和重新创建相同的文件,你能直接清除它吗?

像这样的东西应该为你工作:

FileStream f = File.Open(@[filename], FileMode.Create);
f.Close();

您可以使用System.IO.FileInfo.Delete删除文件,然后在重新创建文件之前使用System.IO.FileInfo.Refresh()。刷新应该阻止在重新创建文件时发生异常。或者如nycdan所说,使用FileMode。创建枚举。