【问题标题】:FileSystem watcher onChanged after file Copy文件复制后的文件系统观察程序 onChanged
【发布时间】:2015-01-29 17:16:42
【问题描述】:

此代码来自另一个堆栈答案,基本上我正在尝试查看用户文件夹中的新文件,我知道 OnCreate 会在新文档完全“复制/下载”之前触发,我正在尝试什么要做的是在每个 onChange 事件中复制它,但是尽管 Microsoft 文档说它完成,但复制似乎不会触发 onChange?

作为记录 onCreate 工作正常。 waitingForClose 被声明为公共字符串列表,onCreate 添加文件罚款。

   private void MetroWindow_Loaded(object sender, RoutedEventArgs e)
    {
        FileSystemWatcher watcher = new FileSystemWatcher();
        watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.Size;
        watcher.Path = @"C:\Users\MyUser";
        watcher.IncludeSubdirectories = true;
        watcher.Created += new FileSystemEventHandler(onCreate);
        watcher.Changed += new FileSystemEventHandler(onChanged);
        watcher.EnableRaisingEvents = true;
    }

onCreate - 这会触发:

  void onCreate(object sender, FileSystemEventArgs e)
    {
        var fileName = e.Name;
        var destPath = @"C:\Users\myUser\Desktop\someFolder";
        var destfile = System.IO.Path.Combine(destPath, fileName);
        if (fileName.Substring(fileName.Length - 3, 3) == "doc" || fileName.Substring(fileName.Length - 3, 3) == "pdf" || fileName.Substring(fileName.Length - 4, 4) == "docx")
        {
            try
            {
                System.IO.File.Copy(e.FullPath, destfile, true);
            }
            catch
            {
                waitingForClose.Add(e.FullPath);
            }
          Console.WriteLine("File:" + e.FullPath + " " + e.ChangeType);

        }
    }

onChanged- 这永远不会触发文件,即使在复制期间也是如此:

void onChanged(object sender, FileSystemEventArgs e)
{
    var fileName = e.Name;
    var destPath = @"C:\Users\myUser\Desktop\someFolder";
    var destfile = System.IO.Path.Combine(destPath, fileName);

    if (fileName.Substring(fileName.Length - 3, 3) == "doc" || fileName.Substring(fileName.Length - 3, 3) == "pdf" || fileName.Substring(fileName.Length - 4, 4) == "docx")
    {


        if (waitingForClose.Contains(e.FullPath))
        {
            try
            {
                System.IO.File.Copy(e.FullPath, destfile, true);
                waitingForClose.Remove(e.FullPath);
            }
            catch { }
        }
    }

}

好吧,从外观上看,这是一个 Windows 8 问题,很快就会发布解决方案!

【问题讨论】:

  • 本质上,如果您正在监听目录的更改并且向其中添加了一个新文件,但由于某种原因没有更新目录的元数据,则不会触发。也许您只是想列出该目录中的所有文件并将它们与之前的列表进行比较以查看是否有任何新文件?
  • 刚刚发现另一篇关于 Windows 8 问题的文章,现在就去检查一下!
  • 好吧,祝你好运。顺便说一句,这是一个地铁应用程序吗?您的函数名称似乎暗示了这一点,但根据您尝试使用的代码,我会说不...
  • 它是一个带有 Metro 主题的 WPF 应用程序

标签: c# filesystemwatcher


【解决方案1】:

好的,

从外观上看,FilesystemWatcher onChanged 事件在 Windows 8.1 中充其量是不确定的(目前已损坏)。

我最终做的是从 onCreate 创建一个文件数组,然后尝试每 5 秒从该数组复制一次:像这样:

   void onCreate(object sender, FileSystemEventArgs e)
    {
        var fileName = e.Name;
        var destPath = @"C:\Users\myuser\Desktop\Repo";
        var destfile = System.IO.Path.Combine(destPath, fileName);
        if (fileName.Substring(fileName.Length - 3, 3) == "doc" || fileName.Substring(fileName.Length - 3, 3) == "pdf" || fileName.Substring(fileName.Length - 4, 4) == "docx")
        {
// We don't want to track the file if it's triggered a created event because it's copied to our repo.
            if (!fileName.Contains("Repo"))
            {
                try
                {
                    System.IO.File.Copy(e.FullPath, destfile, true);
                }
                catch
                {
                   waitingForClose.Add(e.FullPath);
                }
                Console.WriteLine("File:" + e.FullPath + " " + e.ChangeType);

            } // if (!fileName.Contains("repo"))
        } //  if (fileName.Substring(fileName.Length
    } // void onCreate(

所以现在我们有一个文件数组,我们正在等待实际完成创建我正在 Window_onLoad 事件中执行此操作:

   System.Windows.Threading.DispatcherTimer dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
    dispatcherTimer.Tick += new EventHandler(onTick);
    dispatcherTimer.Interval = new TimeSpan(0, 0, 5);
    dispatcherTimer.Start();

现在在 OnTick 活动中

  void onTick(object sender, EventArgs e)
    {
        List<String> tempList = new System.Collections.Generic.List<String>();

        foreach(String item in waitingForClose){

              try
              {
                    System.IO.File.Copy(System.IO.Path.GetFullPath(item), @"C:\Users\myuser\Desktop\Repo\" + System.IO.Path.GetFileName(item), true);
                    tempList.Add(item);
                }
                catch  {
                    // Do nothing
                }
            }
        waitingForClose.RemoveAll(i => tempList.Contains(i));
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-13
    相关资源
    最近更新 更多