从 C# 中的监视文件夹中移动文件

发布于 2024-09-29 02:57:31 字数 419 浏览 9 评论 0原文

我正在使用 FileSystemWatcher,它使用 Created 事件来侦听何时将文件复制到此目录中。这个方法如下:

private void fileSystemWatcher1_Created(object sender, System.IO.FileSystemEventArgs e)
{
   System.IO.Directory.Move(fileSystemWatcher1.Path+@"\"+e.Name, fileSystemWatcher1.Path + @"\Processing\"+e.Name);
}

问题是,如果我将一个大文件复制到这个目录中,这样复制需要大约 30 秒,一旦第一个字节写入文件夹并尝试移动一个文件,就会调用此方法正在被另一个进程使用,因此失败。

有什么想法吗?

谢谢

I am using a FileSystemWatcher which uses the Created event to listen for when I copy files into this directory. this method is below:

private void fileSystemWatcher1_Created(object sender, System.IO.FileSystemEventArgs e)
{
   System.IO.Directory.Move(fileSystemWatcher1.Path+@"\"+e.Name, fileSystemWatcher1.Path + @"\Processing\"+e.Name);
}

The problem is if I copy a big file into this directory, such that it takes about 30 seconds to copy, this method is called as soon as the first byte is written to the folder and tries to move a file which is being used by another process so fails.

Any thoughts?

thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

失退 2024-10-06 02:57:31

您可能需要结合几个解决方案才能实现此目的。

  1. 当事件触发时,启动计时器等待一段时间(30 秒?),以便文件创建有时间完成。然后将文件移走。

  2. 捕获错误并稍后重试。

或者,当文件到达时,将其名称添加到队列中,然后使用单独的进程将文件移出队列。在这种情况下,如果您收到“文件正在使用”错误,您可以简单地将文件读到队列后面,从而给它更多的时间来完成。

You might need to combine a couple of solutions to get this working.

  1. When the event fires start a timer to wait a while (30 seconds?) so that the file creation has time to complete. Then move the file away.

  2. Trap the error and retry later.

Or when the file arrives add it's name to a queue and then have a separate process that moves files off the queue. In this case if you get a "file in use" error you could simply readd the file to the back of the queue thus giving it more time to complete.

著墨染雨君画夕 2024-10-06 02:57:31

在这种情况下,我喜欢让复制过程使用观察者无法识别的临时文件名来移动文件。

然后我将该文件重命名为其真实名称。重命名只需要很少的时间,并且不会导致文件“正在使用”。

In cases like this, I like to have the copying process move the file over using a temporary filename which will not be recognized by the watcher.

Then I rename the file to its real name. The rename takes very little time and will not cause the file to be "in use".

悲喜皆因你 2024-10-06 02:57:31

也许您可以通过监听“Changed”事件来做到这一点,并且仅在冷静期后尝试复制文件。即收到“Created”后,等待5秒再复制文件,每次收到Changed事件时将时间重置为零。

Perhaps you could do this by also listening to the "Changed" event, and only try to copy the file after a cool-off period. That is, after receiving "Created", wait 5 seconds before copying the file, and reset the time to zero each time you receive the Changed event.

季末如歌 2024-10-06 02:57:31

我已经这样做了:

while(true){
  try
  {
     using (Stream stream = new FileStream("MyFilename.txt"))
     {
        break;
     }
  } catch {
     Thread.Sleep(1000);
  }
}

它似乎可以完成工作

I have done this:

while(true){
  try
  {
     using (Stream stream = new FileStream("MyFilename.txt"))
     {
        break;
     }
  } catch {
     Thread.Sleep(1000);
  }
}

it seems to do the job

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文