【问题标题】:C# FileSystemWatcher Copy folder completeC# FileSystemWatcher 复制文件夹完成
【发布时间】:2015-12-17 03:25:59
【问题描述】:

我正在使用 FileSystemWatcher 来监视将用于进行某些文件重命名的文件夹。
唯一会被复制的是包含文件的文件夹。不会有单个文件放入受监视的文件夹中。这是设置 FileSystemWatcher 的代码

watcher.Path = path;
watcher.NotifyFilter = NotifyFilters.DirectoryName | NotifyFilters.FileName;
watcher.IncludeSubdirectories = true;
watcher.Filter = "*.*";
watcher.Created += new FileSystemEventHandler(watcher_Created);
watcher.Changed += new FileSystemEventHandler(watcher_Changed);
watcher.Renamed += new RenamedEventHandler(watcher_Renamed);
watcher.EnableRaisingEvents = true; 

此设置似乎没有任何问题..

被复制的文件夹大小可以在 50-200mb 之间。有没有办法在开始重命名过程之前检查/确保所有文件都已完成复制。 我试过这个想法,如果在调用 GetFiles() 时复制仍在发生,我会得到一个 IOException。

bool finishedCopying = false;
while (!finishedCopying)
{
    try
    {
        List<FileInfo> fileList = directoryInfo.GetFiles().ToList();
        AlbumSearch newAlbum = new AlbumSearch(directoryInfo);
        return newAlbum;
    }
    catch (IOException)
    {
        finishedCopying = false;
    }
}

如果需要更多信息,请询问我可以提供的信息。

Ta。

【问题讨论】:

  • 我认为您实际上是在要求时间机器。 IsSomeOtherProcessPlanningToWriteMoreFilesToThisLocation 是一个很难编写的函数。
  • 这是不可能的。没有办法区分用户暂时暂停执行移动/复制的程序和他连续两次运行它之间的区别。您对执行此操作的过程一无所知,不要做任何假设。
  • 我希望情况并非如此。我希望在复制过程中可能有一些东西可以访问以从源文件夹中获取信息。甚至像文件数量这样的东西......
  • 根据访问源文件的能力和/或执行写入的系统,您可能会计算文件夹中内容的校验和,并在特定时间间隔将其与目的地的校验和。如果它们匹配,则复制将被验证。

标签: c# filesystemwatcher copying


【解决方案1】:

这是一个小型演示应用程序,它在开始时检查文件,然后使用两个哈希集来跟踪复制的文件。这仅在源目录已知的情况下才有效。无法知道文件是从文件副本创建的还是直接创建的,因此您只能将两个已知目录与 Directory.GetFiles 进行比较。而且,正如在 cmets 中已经说过的,您仍然需要检查在复制过程中是否在旧目录中添加/删除/重命名了其他文件

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        static HashSet<string> oldDirFiles = new HashSet<string>();
        static HashSet<string> newDirFiles = new HashSet<string>();

        static string oldDir = "C:\\New Folder";
        static string newDir = "C:\\New Folder 2";

        static System.Threading.ManualResetEvent resetEvent = new System.Threading.ManualResetEvent(false);

        static void Main(string[] args)
        {
            System.IO.FileSystemWatcher watcher = new System.IO.FileSystemWatcher();
            watcher.Path = newDir;
            watcher.NotifyFilter = NotifyFilters.DirectoryName | NotifyFilters.FileName;
            watcher.IncludeSubdirectories = true;
            watcher.Filter = "*.*";
            watcher.Created += watcher_Created;
            watcher.Changed += watcher_Changed;
            watcher.Renamed += watcher_Renamed;
            watcher.EnableRaisingEvents = true;

            //get all files in old directory
            var oldFiles = Directory.GetFiles(oldDir, "*.*", SearchOption.AllDirectories);
            foreach (var file in oldFiles)
                oldDirFiles.Add(file);

            resetEvent.WaitOne();

            //now launch the directory copy

            //then you have to check if in the meaning time, new files were added or renamed
            //that could be done also with a watcher in the old directory
        }

        static void watcher_Renamed(object sender, RenamedEventArgs e)
        {
            throw new NotImplementedException();
        }

        static void watcher_Changed(object sender, FileSystemEventArgs e)
        {
            throw new NotImplementedException();
        }

        static void watcher_Created(object sender, FileSystemEventArgs e)
        {
            //check if the copied file was in the old directory before starting
            if (oldDirFiles.Contains(e.FullPath.Replace(newDir, oldDir)))
            {
                newDirFiles.Add(e.FullPath);
                //if all the files have been copied, the file count will be the same in the two hashsets
                //the resetevent.Set() signal the waiting thread and the program can proceed
                if (newDirFiles.Count == oldDirFiles.Count)
                    resetEvent.Set();
            }
        }
    }
}

【讨论】:

  • 据我了解 OP 的问题,他们的代码不是 执行 复制。因此,没有简单的方法可以找到复制的来源(因此 cmets 关于困难 - 如果是他们自己的代码进行复制,那么只需安排该代码在结束 - 根本不需要 FSW)
  • 我也认为,否则您只需等待复制过程完成,无需任何等待/线程等。
  • @Damien_The_Unbeliever 没错,我的代码没有复制。我将手动将一个文件夹拖到受监控的文件夹中,因此 windows 将处理复制。
  • 我的应用程序实际上是为了监视来自外部的文件副本(例如:来自 Windows 副本)。尝试应用程序并在程序在 resetEvent.WaitOne() 处停止时开始复制;线。然后看看你是否可以在你的解决方案中使用这种方法。
  • 另一种方法可能是在三个事件(重命名、更改和创建)上检查源目录和目标目录上的文件列表(使用 Directory.GetFiles(directory, ". i>", SearchOption.AllDirectories) 并进行比较。当源目录中的所有文件也都在目标目录中时,文件复制完成。
【解决方案2】:

我使用计时器试了一下。它可能不是最漂亮的解决方案,但在最初的测试中,它似乎到目前为止还有效。本质上,这是在将文件夹复制到受监视文件夹时,它会将文件夹路径添加到 AlbumList。该文件夹中的文件将触发 Created 事件。这将等待文件完成复制。完成后,它会启动一个计时器。如果触发了新的 Created 事件,则计时器将自行重置。

当触发 timer.elapsed 事件时,它假设(我知道假设是所有 f*&k ups 的母亲)没有更多文件要复制并且可以开始处理完全复制的文件夹..

System.Timers.Timer eventTimer = new System.Timers.Timer(); 
List<string> AlbumList = new List<string>();

private void watcher_Created(object sender, FileSystemEventArgs e)
{    
    if (Directory.Exists(e.FullPath))
    {
        AlbumList.Add(e.FullPath);
    }

    if (File.Exists(e.FullPath))
    {
        eventTimer.Stop();
        FileInfo newTrack = new FileInfo(e.FullPath);
        while (IsFileLocked(newTrack))
        {
            // File is locked. Do Nothing..
        }
        eventTimer.Start();              
    }
}

private void eventTimer_Elapsed(object sender, ElapsedEventArgs e)
{
    List<string> ItemToRemove = new List<string>();
    foreach (var item in AlbumList)
    {            
        DirectoryInfo di = new DirectoryInfo(item);
        AlbumSearch newAlbum = new AlbumSearch(di);

        if (DoSomethingMethod(newAlbum))
        {
            ItemToRemove.Add(item);
        }
        else
        {
            // why did it fail
        }
    }

    foreach (var path in ItemToRemove)
    {
        AlbumList.Remove(path);
    }
}

private bool DoSomethingMethod(AlbumSearch as)
{
    // Do stuff here 
    return true;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多