且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何确定文件夹是否已完成复制C#

更新时间:2023-11-28 19:04:10

不幸的是FileSystemWatcher没有告诉文件写入完毕后显示您。因此,您的选择是...


  1. 设置最后一次写入后的超时时间(假设没有更多更改发生)

  2. 编写应用程序放置了一个各种各样的锁文件,该文件告诉其他程序已完成。

之后重新阅读您的问题……听起来好像您对其他应用程序没有任何控制权。



所以您将需要某种超时值来确定何时所有的写作都完成了。基本上创建一个计时器,该计时器在每个filesystemwatcher事件发生后重置……当它超时时,您将触发一个表明已完成的事件。到您的代码...

  static void Main(string [] args)
{
计时器。间隔= 5000; // 5秒-更改为适当的
Timer.AutoReset = false;
Timer.Elapsed + = TimeoutDone;
字符串路径= @ D:\音乐;
FileSystemWatcher mWatcher = new FileSystemWatcher();
mWatcher.Path =路径;
mWatcher.NotifyFilter = NotifyFilters.LastAccess;
mWatcher.NotifyFilter = mWatcher.NotifyFilter | NotifyFilters.LastWrite;
mWatcher.NotifyFilter = mWatcher.NotifyFilter | NotifyFilters.DirectoryName;
mWatcher.IncludeSubdirectories = true;
mWatcher.Created + = new FileSystemEventHandler(mLastChange);
mWatcher.Changed + = new FileSystemEventHandler(mLastChange);

mWatcher.EnableRaisingEvents = true;
Console.WriteLine(观看路径: +路径);
Timer.Start();

字符串出口;
而(true)
{
exit = Console.ReadLine();
如果(exit == exit)
中断;

}
}

private static Timer Timer = new Timer();

私有静态void TimeoutDone(对象源,ElapsedEventArgs e)
{
Console.WriteLine( Timerlapsed!);
}

private static void mLastChange(Object sender,FileSystemEventArgs e)
{
Console.WriteLine(e.ChangeType + + e.FullPath);
if(Timer!= null)
{
Timer.Stop();
Timer.Start();
}
}


I have a question: How do I determine whether a folder has finished copying from one location to another?

At the moment my FileSystemWatcher triggers several events as soon as a file within the directory being copied. What I want though, is one single event to be triggered when all the files within that folder has been successfully copied. My code right now looks like this:

static void Main(string[] args)
    {
        String path = @"D:\Music";
        FileSystemWatcher mWatcher = new FileSystemWatcher();
        mWatcher.Path = path;
        mWatcher.NotifyFilter = NotifyFilters.LastAccess;
        mWatcher.NotifyFilter = mWatcher.NotifyFilter | NotifyFilters.LastWrite;
        mWatcher.NotifyFilter = mWatcher.NotifyFilter | NotifyFilters.DirectoryName;
        mWatcher.IncludeSubdirectories = true;
        mWatcher.Created += new FileSystemEventHandler(mLastChange);
        mWatcher.Changed += new FileSystemEventHandler(mLastChange);

        mWatcher.EnableRaisingEvents = true;
        Console.WriteLine("Watching path: " + path);



        String exit;
        while (true)
        {
               exit = Console.ReadLine();
               if (exit == "exit")
                   break;

        }


    }



    private static void mLastChange(Object sender, FileSystemEventArgs e)
    {
        Console.WriteLine(e.ChangeType + " " + e.FullPath);
    }

Unfortunately FileSystemWatcher doesn't tell you when a file is finished writing. So your options are...

  1. Set a timeout after last write when it is assumed there are no more changes coming
  2. Have the writing application put a lock file of some variety that tells any other program that it's done.

After re-reading your question... it doesn't sound like you have any control over the other application.

So you will need some kind of timeout value that determines when all the writing is done. Basically create a timer that resets after each filesystemwatcher event... when it times out then you fire the single event that says it's done.

Here is how you could add it to your code...

static void Main(string[] args)
{
    Timer.Interval = 5000; // 5 seconds - change to whatever is appropriate
    Timer.AutoReset = false;
    Timer.Elapsed += TimeoutDone;
    String path = @"D:\Music";
    FileSystemWatcher mWatcher = new FileSystemWatcher();
    mWatcher.Path = path;
    mWatcher.NotifyFilter = NotifyFilters.LastAccess;
    mWatcher.NotifyFilter = mWatcher.NotifyFilter | NotifyFilters.LastWrite;
    mWatcher.NotifyFilter = mWatcher.NotifyFilter | NotifyFilters.DirectoryName;
    mWatcher.IncludeSubdirectories = true;
    mWatcher.Created += new FileSystemEventHandler(mLastChange);
    mWatcher.Changed += new FileSystemEventHandler(mLastChange);

    mWatcher.EnableRaisingEvents = true;
    Console.WriteLine("Watching path: " + path);
    Timer.Start();

    String exit;
    while (true)
    {
        exit = Console.ReadLine();
        if (exit == "exit")
            break;

    }
}

private static Timer Timer = new Timer();

private static void TimeoutDone(object source, ElapsedEventArgs e)
{
    Console.WriteLine("Timer elapsed!");
}

private static void mLastChange(Object sender, FileSystemEventArgs e)
{
    Console.WriteLine(e.ChangeType + " " + e.FullPath);
    if (Timer != null)
    {
        Timer.Stop();
        Timer.Start();
    }
}