4

質問があります: ある場所から別の場所へのフォルダーのコピーが完了したかどうかを確認するにはどうすればよいですか?

現在、私の FileSystemWatcher は、ディレクトリ内のファイルがコピーされるとすぐにいくつかのイベントをトリガーします。ただし、そのフォルダー内のすべてのファイルが正常にコピーされたときにトリガーされる単一のイベントが必要です。私のコードは今次のようになります:

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);
    }
4

5 に答える 5

2

残念ながら、FileSystemWatcher は、ファイルの書き込みがいつ終了したかを通知しません。だからあなたのオプションは...

  1. これ以上変更がないと想定される場合は、最後の書き込み後にタイムアウトを設定します
  2. 書き込みアプリケーションに、他のプログラムに書き込みが完了したことを知らせる、さまざまなロック ファイルを配置させます。

質問を読み直した後...他のアプリケーションを制御しているようには見えません。

そのため、すべての書き込みがいつ完了するかを決定する何らかのタイムアウト値が必要になります。基本的に、各 filesystemwatcher イベントの後にリセットするタイマーを作成します...タイムアウトすると、完了したことを示す単一のイベントが発生します。

これをコードに追加する方法は次のとおりです...

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();
    }
}
于 2013-07-12T18:41:01.763 に答える
0

宛先がローカル フォルダーの場合、ファイル システム フィルター ドライバーを使用して、ファイルの作成イベントファイルを閉じるイベントを追跡できます。以前に作成されたすべてのファイルがいつ閉じられるかを知ることで、コピーが完了したことが通知されます。

于 2013-07-14T16:47:43.473 に答える
0

残念ながら、すぐに使える解決策はありません。しかし、私は(コピーが終了した)イベントをトリガーするための簡単でトリッキーなソリューションを設計しました。

タイマーを使用する必要があります。

        FileSystemWatcher fsw = new FileSystemWatcher();
        string fullPath = "";
        DateTime tempTime;
        fsw.Path = @"C:\temp";

        private void startwatching()
        {
            timer1.Start();
        }
        fsw.EnableRaisingEvents = true;
        fsw.Created += Fsw_Created;

        private void Fsw_Created(object sender, FileSystemEventArgs e)
        {
            tempTime = DateTime.Now.AddSeconds(-4);
            fullPath = e.FullPath;
        }

    private void timer1_Tick(object sender, EventArgs e)
    {
        if (fullPath!=string.Empty)
        {
            timer1.Stop();
            if (tempTime >= Directory.GetLastAccessTime(fullPath))
            {
                DirectoryInfo di = new DirectoryInfo(fullPath);
                listBox1.Items.Add("Folder " + di.Name + " finished copying");
                fullPath = string.Empty;
            }
            else
            {
                tempTime = DateTime.Now;
            }
            timer1.Start();
        }
    }
于 2019-08-21T11:40:15.437 に答える