FileSystemWatcher для мониторинга перемещенных файлов

1

Возможный дубликат:
Обнаружение перемещенных файлов с помощью FileSystemWatcher

Я пытаюсь отслеживать перемещенные файлы с помощью FileSystemWatcher и получаю некоторую помощь по пути здесь:

Использование FileSystemWatcher с несколькими файлами

Однако, я обнаружил, что должен был использовать как удаленные, так и созданные события, чтобы получить пути, из которых были перемещены файлы, а также путь туда, где они были перемещены. Но когда я добавляю аналогичный код для события Delete, я могу получить только одно или другое событие для запуска. И, похоже, это порядок того, где я провожу события, определяющие, какое событие будет выполняться. Поэтому, если я поместил событие "Создано" последним в код проводки, который будет запущен, и наоборот, если я положу проводку "Удалить" последним, который будет запущен, но не создан.

Здесь код:

public class FileListEventArgs : EventArgs
{
    public List<string> FileList { get; set; }
}

public class Monitor
{
    private List<string> filePaths;
    private List<string> deletedFilePaths;
    private ReaderWriterLockSlim rwlock;
    private Timer processTimer;
    private Timer deletionTimer;
    public event EventHandler FileListCreated;
    public event EventHandler FileListDeleted;


    public void OnFileListCreated(FileListEventArgs e)
    {
        if (FileListCreated != null)
            FileListCreated(this, e);
    }

    public void OnFileListDeleted(FileListEventArgs e)
    {
        if (FileListDeleted != null)
            FileListDeleted(this, e);
    }

    public Monitor(string path)
    {
        filePaths = new List<string>();
        deletedFilePaths = new List<string>();

        rwlock = new ReaderWriterLockSlim();

        FileSystemWatcher watcher = new FileSystemWatcher();
        watcher.Filter = "*.*";
        watcher.Deleted += new FileSystemEventHandler(watcher_Deleted);
        watcher.Created += watcher_FileCreated;


        watcher.Path = path;
        watcher.IncludeSubdirectories = true;
        watcher.EnableRaisingEvents = true;
    }


    private void ProcessQueue()
    {
        try
        {
            Console.WriteLine("Processing queue, " + filePaths.Count + " files created:");
            rwlock.EnterReadLock();

        }
        finally
        {
            if (processTimer != null)
            {
                processTimer.Stop();
                processTimer.Dispose();
                processTimer = null;
                OnFileListCreated(new FileListEventArgs { FileList = filePaths });
                filePaths.Clear();
            }
            rwlock.ExitReadLock();
        }
    }

    private void ProcessDeletionQueue()
    {
        try
        {
            Console.WriteLine("Processing queue, " + deletedFilePaths.Count + " files created:");
            rwlock.EnterReadLock();

        }
        finally
        {
            if (processTimer != null)
            {
                processTimer.Stop();
                processTimer.Dispose();
                processTimer = null;
                OnFileListDeleted(new FileListEventArgs { FileList = deletedFilePaths });

                deletedFilePaths.Clear();
            }
            rwlock.ExitReadLock();
        }
    }

    void watcher_FileCreated(object sender, FileSystemEventArgs e)
    {
        try
        {
            rwlock.EnterWriteLock();
            filePaths.Add(e.FullPath);

            if (processTimer == null)
            {
                // First file, start timer.
                processTimer = new Timer(2000);
                processTimer.Elapsed += (o, ee) => ProcessQueue();
                processTimer.Start();
            }
            else
            {
                // Subsequent file, reset timer. 
                processTimer.Stop();
                processTimer.Start();
            }

        }
        finally
        {
            rwlock.ExitWriteLock();
        }
    }

    void watcher_Deleted(object sender, FileSystemEventArgs e)
    {
        try
        {
            rwlock.EnterWriteLock();
            deletedFilePaths.Add(e.FullPath);

            if (deletionTimer == null)
            {
                // First file, start timer.
                deletionTimer = new Timer(2000);
                deletionTimer.Elapsed += (o, ee) => ProcessDeletionQueue();
                deletionTimer.Start();
            }
            else
            {
                // Subsequent file, reset timer. 
                deletionTimer.Stop();
                deletionTimer.Start();
            }

        }
        finally
        {
            rwlock.ExitWriteLock();
        }
    }

Итак, как мне это сделать, чтобы получить исходный путь, где были файлы, а также новый путь туда, куда они были перемещены? (Посмотрите первый вопрос, почему код таймера существует, чтобы приостановить обработку событий до тех пор, пока все файлы не будут перемещены в многоточечном перемещении).

  • 0
    Я так не думаю. У меня нет проблем с использованием имени файла для сравнения файлов, как в этом посте. Проблема в том, что я не могу заставить и удалить, и создать события для запуска. Или, по крайней мере, все, что я вижу, это то, что событие create запущено, а удаление еще не сделано. В моем основном классе мне нужно взять список созданных файлов и сравнить его со списком удаленных файлов, но список удаленных файлов пуст, а список созданных файлов заполнен.
Теги:
filesystemwatcher

2 ответа

1
Лучший ответ

Вы объявляете два таймера, но используете только один из них (вы используете тот же метод в методе удаления процесса). Так что сначала мы начинаем с простой ошибки копирования/вставки.

  • 0
    Спасибо, это была попытка заставить меня работать, но я пропустил изменение некоторых вещей с копией и вставкой, как вы сказали. Это не помогло исправить эту ошибку, но заставило меня снова просмотреть ее, и я обнаружил, что, если я запустил оба события в одном и том же методе ProcessQueue, это сработало, так что я вам за это благодарен.
0

Я обнаружил, что события FileSystemWatcher НЕ поставлены в очередь (caveat: это было около 8 лет назад).

Если вы обрабатываете файл и создаете 3 новых файла во время обработки, вы не получите 3 события.

После обработки файла вам может потребоваться вручную проверить каталог для других изменений.

  • 0
    Ну, я получаю 3 события для перемещения 3 файлов ... Но проблема в том, что я не могу получить и событие удаления, и событие создания для запуска, только одно или другое.
  • 0
    Вы просто контролируете ОДИН каталог? Если вы перемещаете файл, он не может оставаться в том же каталоге. Если файл удален, вы получите удаленное событие. Если файл перемещен, вы получите созданное событие. Я не понимаю, как вы могли бы получить оба.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню