Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

FileSystemWatcher

270
31 марта 2009 года
Drew
265 / / 20.07.2000
есть простой код:

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace TestFSW
{
class Program
{
static string pt = null;

static void Main(string[] args)
{
FileSystemWatcher fsw = new FileSystemWatcher(@"c:\temp");
fsw.Filter = "*.*";
fsw.Created += new FileSystemEventHandler(fsw_Created);
fsw.EnableRaisingEvents = true;
Console.ReadKey();
}

static void fsw_Created(object sender, FileSystemEventArgs e)
{
Console.WriteLine(e.FullPath);
File.Delete(e.FullPath); - вот тут и лажа!!!!
}
}
}

нужно каким-то образом, получив событие о создании файла, ... ну скажем, просто его (файл) удалить.
5
31 марта 2009 года
hardcase
4.5K / / 09.08.2005
Цитата: Drew

 
Код:
static void fsw_Created(object sender, FileSystemEventArgs e)
        {
            Console.WriteLine(e.FullPath);
            File.Delete(e.FullPath);                       - вот тут и лажа!!!!
        }
    }
}

Программа, которая создала файл, по видимому еще не закрыла его (пишет в него или просто держит хэндл). Поэтому операционная система отклоняет запрос на удаление.

Наиболее оптимальный вариант - дождаться пока программа закроет хэндл на файл и потом его удалить: формируем список файлов, и периодически обходим его в цикле, пробуя удалять каждый.

270
31 марта 2009 года
Drew
265 / / 20.07.2000
ну про это-то я догадался...
держит его как раз FileSystemWatcher!!!! что следует из кода...

меня интересует, почему он его держит и когда отпустит!

может, я что-то НЕ ТО делаю?!
5
01 апреля 2009 года
hardcase
4.5K / / 09.08.2005
Цитата: Drew
ну про это-то я догадался...
держит его как раз FileSystemWatcher!!!! что следует из кода...

Файловый монитор не держит хэндлов на файл. Повторяю еще раз - хэндл держит сторонняя программа, которая создала файл.

270
01 апреля 2009 года
Drew
265 / / 20.07.2000
чтобы проверить - достаточно скомпилировать и запустить
(не удивляет, что он такой короткий?... - это просто тест чтобы как раз отбросить все другие возможности)
5
01 апреля 2009 года
hardcase
4.5K / / 09.08.2005
Цитата: Drew
чтобы проверить - достаточно скомпилировать и запустить
(не удивляет, что он такой короткий?... - это просто тест чтобы как раз отбросить все другие возможности)


У меня есть система, которая на основе этого компонента обрабатывает несколько тысяч файлов разом. Я вам в ТРЕТИЙ раз говорю (дальше буду капать в карму) - хэндл держит программа-постовщик файлов.

В тот момент, когда сторонняя программа выполняет CreateFile и только создает файл на диске, отрабатывает ваш обработчик fsw_Created и вы пытаетесь удалить его, но хэндл все еще занят. Нужно дождаться момента, когда хэндл будет освобожден и уже делать с файлом все что угодно.

270
01 апреля 2009 года
Drew
265 / / 20.07.2000
можете добавить в код пару строк чтобы заработало?
5
01 апреля 2009 года
hardcase
4.5K / / 09.08.2005
Цитата: Drew
можете добавить в код пару строк чтобы заработало?


Код:
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Threading;

namespace ConsoleApplication17 {
    class Program {
        static void Main(string[] args) {
            MyFileMonitor file_mon = new MyFileMonitor(@"C:\TMP");
            file_mon.Start();
            Console.ReadLine();
            file_mon.Stop();
        }
    }

    public sealed class MyFileMonitor {

        private const int WATCHER_BUFFER_SIZE = 102400; // 100k

        private const int FILE_QUEUE_MAX_LENGTH = WATCHER_BUFFER_SIZE / 16;

        public MyFileMonitor(string source_path) {
            reader_sem = new Semaphore(0, FILE_QUEUE_MAX_LENGTH);
            writer_sem = new Semaphore(FILE_QUEUE_MAX_LENGTH, FILE_QUEUE_MAX_LENGTH);
            file_queue = new Queue<string>(FILE_QUEUE_MAX_LENGTH);

            file_watcher = new FileSystemWatcher(source_path);
            //file_watcher.IncludeSubdirectories = true;
            file_watcher.Created += FileEvent;
            file_watcher.InternalBufferSize = WATCHER_BUFFER_SIZE;
        }

        private void FileEvent(object sender, FileSystemEventArgs e) {
            Console.WriteLine("Tracking '{0}'.", e.FullPath);
            Enqueue(e.FullPath);
        }

        private Semaphore reader_sem;
        private Semaphore writer_sem;
        private Queue<string> file_queue;
        private Thread working_thread = null;

        private void Enqueue(string file_name) {
            writer_sem.WaitOne();
            lock (file_queue) {
                file_queue.Enqueue(file_name);
            }
            reader_sem.Release();
        }

        private bool Dequeue(out string file_name, TimeSpan timeout) {
            file_name = null;
            if (reader_sem.WaitOne(timeout, false)) {
                lock (file_queue) {
                    file_name = file_queue.Dequeue();
                }
                writer_sem.Release();
                return true;
            }
            return false;
        }

        private bool TryOpenFile(FileInfo file_info, out FileStream stream) {
            try {
                stream = file_info.Open(FileMode.Open, FileAccess.Read, FileShare.None);
                return true;
            } catch (IOException) {
                stream = null;
                return false;
            }
        }

        private void ProcessFile(string file_name) {
            try {
                FileInfo file_info = new FileInfo(file_name);
                if (file_info.Exists) {
                    FileStream stream = null;
                    while (file_info.Exists && !TryOpenFile(file_info, out stream)) {
                        Thread.Sleep(100);
                        file_info.Refresh();
                    }
                    if (stream != null) {
                        using (StreamReader reader = new StreamReader(stream)) {
                            Console.WriteLine("[{0}] Processing file {1}", DateTime.Now, file_info.Name);
                            // читаем файл.....
                        }
                    }
                    file_info.Delete();
                }
            } catch (Exception error) {
                Console.WriteLine("An error caused during processing file {0}:", file_name);
                Console.WriteLine(error.ToString());
            }
        }

        private void WorkingThread() {
            while (_working) {
                string file_name;
                if (Dequeue(out file_name, new TimeSpan(0, 0, 0, 0, 100))) {
                    ProcessFile(file_name);
                }
            }
        }

        private FileSystemWatcher file_watcher;

        private bool _working = false;

        public void Start() {
            if (!_working) {
                working_thread = new Thread(WorkingThread);
                working_thread.Start();
                file_watcher.EnableRaisingEvents = true;
                _working = true;
            }
        }

        public void Stop() {
            if (_working) {
                file_watcher.EnableRaisingEvents = false;
                _working = false;
                working_thread.Join();
            }
        }

        public bool Listening {
            get {
                return _working;
            }
        }
    }
}
270
01 апреля 2009 года
Drew
265 / / 20.07.2000
static void fsw_Created(object sender, FileSystemEventArgs e)
{
Console.WriteLine(e.FullPath);
bool tr=false;
while (!tr)
{
tr = true;
try
{
File.Delete(e.FullPath);
}
catch (IOException ex)
{
Console.WriteLine("{0}", ex.Message);
tr = false;
}
catch (Exception ex)
{
Console.WriteLine("{0}", ex.Message);
tr = false;
}
}
Console.WriteLine("Файл {0} удален", e.FullPath);
}
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог