文件正由另一个进程使用

时间:2010-09-17 17:08:25

标签: c#

我有一个大致这样做的程序:

  1. 打开一个文件以便从中读取。
  2. 关闭文件
  3. 启动filewatcher以观察文件中的更改。
  4. 一旦检测到更改,filewatcher的EnableRaisingEvents标志将设置为false,并且该过程将从步骤1开始重复。
  5. 问题是,在从第4步到第1步之后,它无法读取文件说它正被另一个进程使用。

    我收到错误:

    未处理的异常:System.IO.IOException:进程无法访问文件'c:\ test.xml',因为它正由另一个进程使用。

    出了什么问题?我的程序的第1步的读者是否仍然打开文件,或者是访问该文件的一些完全不同的进程,还是filewatcher在从4移动到步骤1之后仍在观看文件,尽管将标志设置为false?

7 个答案:

答案 0 :(得分:8)

如果您的代码与此类似:

[STAThread]
static void Main(string[] args)
{
    string file = "temp.txt";
    ReadFile(file);
    FileSystemWatcher fswatcher = new FileSystemWatcher(".\\");
    fswatcher.Changed += delegate(object sender, FileSystemEventArgs e)
                             {
                                 ReadFile(e.FullPath);
                             };
    while (true)
    {
        fswatcher.WaitForChanged(WatcherChangeTypes.Changed);
    }
}
private static void ReadFile(string file)
{
    Stream stream = File.OpenRead(file);
    StreamReader streamReader = new StreamReader(stream);
    string str = streamReader.ReadToEnd();
    MessageBox.Show(str);
    streamReader.Close();
    stream.Close();
}

如果您是通过记事本编辑文件,那么,当您单击保存按钮时,它会使文件保持打开状态,就像您只是关闭程序并单击保存时一样。我不知道这是一个bug还是记事本的无证功能,但这可能是你的问题。解决此问题的一种方法是执行以下操作:

在您的匿名代理中,或者在您执行ReadFile()调用Thread.Sleep(1000)的调用的任何地方,让程序在读取文件之前等待,您的代码应该可以正常工作。

答案 1 :(得分:4)

您可以使用http://www.sysinternals.com中的Process Explorer之类的工具来查看谁拥有流程的开放句柄

该文件最有可能因首先触发更改通知而被打开。

答案 2 :(得分:3)

注意:即使在记事本中打开“file.txt”,此代码仍然有效,因为它正在打开以供阅读。

using System;
using System.IO;

class Program
{
  static void Main(string[] args)
  {
    ReadFromFile(@"C:\file.txt");
    Console.ReadLine();
  }

  static void ReadFromFile(string filename)
  {
    string line;
    using (StreamReader sr = File.OpenText(filename))
    {
      line  = sr.ReadLine();
      while (line != null)
      {
        Console.WriteLine(str);
        line = sr.ReadLine();
      }
      sr.Close();
    }
  }
}

或者只是:

string text = System.IO.File.ReadAllText(@"C:\file.txt");

答案 3 :(得分:3)

除了其他答案之外,有可能当FileWatcher对文件做出反应时,该应用尚未关闭。在步骤1中尽量不要立即失败,但尝试多次尝试并延迟很短。

答案 4 :(得分:1)

问题是FileSystemWatcher会立即告诉您文件的创建时间。它不会等待文件被释放。 例如,当您复制一个需要3秒钟复制的大文件时,您必须在此之后打开该文件。

http://www.codeproject.com/Questions/461666/FileSystemWatcher-issue-in-windows-application Wait until file is unlocked in .NET

答案 5 :(得分:0)

有很多事情可以发生。

首先,确保通过在实现IDisposable的所有内容周围使用using子句来正确处理文件编写器(close不够好)。

其次,您只是阅读,确保在打开文件时设置了正确的标志。

如果你提供一个显示你如何完成这个的代码块,那么它会更进一步。特别是在阅读文件

答案 6 :(得分:0)

您可以使用此MS实用程序openfiles获取已打开文件的列表,并了解谁已打开该文件。

openfiles /query

它还允许断开网络用户打开的文件。

openfiles /disconnect /id XXXX

如果要将它用于本地PC,则应设置维护对象列表全局标记:

openfiles /local on

按照link获取更多详细信息。