【问题标题】:FileSystemWatcher - unable to read created fileFileSystemWatcher - 无法读取创建的文件
【发布时间】:2015-02-03 14:50:56
【问题描述】:

我最近开始使用FileSystemWatcher。我需要监视某个目录,并且添加到该目录的任何新文件都会获取 MD5 校验和并将其显示在控制台中。所以我添加了适当的事件处理程序

watcher.Created += new FileSystemEventHandler(OnCreated);

那么OnCreated 看起来像

private static void OnCreated(object sender, FileSystemEventArgs e)
  {
      using (var md5 = MD5.Create())
      {
          using (var stream = File.OpenRead("C:\\Test\\Uploads\\"+ e.Name))
          {
              byte[] checkSum = md5.ComputeHash(stream);

              StringBuilder sb = new StringBuilder();
              for (int i = 0; i < checkSum.Length; i++)
              {
                  sb.Append(checkSum[i].ToString());
              }

              Console.WriteLine(sb.ToString());
          }
      }
  }

当创建第一个文件时,这工作得很好,但是一旦在目录中创建另一个文件,我就会收到以下错误

附加信息:进程无法访问文件 'C:\Test\Uploads\New Text Document (2).txt',因为它正被另一个进程使用

抛出错误的行是

using (var stream = File.OpenRead("C:\\Test\\Uploads\\"+ e.Name))

我也尝试过stream.Dispose();,但遇到了同样的问题。有谁知道我要去哪里错了?提前感谢您的所有帮助和支持。

【问题讨论】:

  • 也许它正被 另一个 进程使用 - 也许文件没有被创建/写入?
  • e.Name 是否总是包含新创建文件的名称?
  • @silent 是的,它总是有新创建文件的名称
  • hm,您是否尝试过在尝试打开文件之前插入几秒钟的睡眠?也许您的事件处理程序被触发并且文件尚未完全创建
  • @dariogriffo 感谢您提供的信息,但我更愿意在没有Thread.Sleep(1000) 的情况下使用它。出于我的原因,您可以参考this 答案

标签: c# file-watcher


【解决方案1】:

如上所述,通过重试尝试这个简单的超时

        using (var md5 = MD5.Create())
        {
            int retries = 10;
            while (retries > 0)
            {
                try
                {
                    using (var stream = File.OpenRead("C:\\Test\\Uploads\\" + e.Name))
                    {
                        byte[] checkSum = md5.ComputeHash(stream);

                        StringBuilder sb = new StringBuilder();
                        for (int i = 0; i < checkSum.Length; i++)
                        {
                            sb.Append(checkSum[i].ToString());
                        }
                    }
                    // All done, leave the loop
                    break;
                }
                catch (FileNotFoundException e)
                {
                    // Check for your specific exception here
                    retries--;
                    Thread.Sleep(1000);
                }
            }
            // Do some error handling if retries is 0 here
        }

请注意,在 Catch 块中,您必须正确检查您的特定错误。在任何其他情况下,您都想处理异常。

【讨论】:

  • 为什么不简单地捕捉FileNotFoundException
  • @silent 您的代码似乎给了我完全相同的错误:/
  • @Code 你是否插入了正确的异常来捕获?我不确定 FileNotFound 是否适合您的情况
  • 我添加了FileNotFoundException,无论它是否正确,我都在想同样的问题
  • 好吧,抛出了什么样的异常?要测试它是否可以正常工作,只需说 catch(Exception e)
猜你喜欢
  • 2018-01-03
  • 1970-01-01
  • 2016-02-11
  • 2018-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多