FileSystemWatcher
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); - вот тут и лажа!!!!
}
}
}
нужно каким-то образом, получив событие о создании файла, ... ну скажем, просто его (файл) удалить.
{
Console.WriteLine(e.FullPath);
File.Delete(e.FullPath); - вот тут и лажа!!!!
}
}
}
Программа, которая создала файл, по видимому еще не закрыла его (пишет в него или просто держит хэндл). Поэтому операционная система отклоняет запрос на удаление.
Наиболее оптимальный вариант - дождаться пока программа закроет хэндл на файл и потом его удалить: формируем список файлов, и периодически обходим его в цикле, пробуя удалять каждый.
держит его как раз FileSystemWatcher!!!! что следует из кода...
меня интересует, почему он его держит и когда отпустит!
может, я что-то НЕ ТО делаю?!
держит его как раз FileSystemWatcher!!!! что следует из кода...
Файловый монитор не держит хэндлов на файл. Повторяю еще раз - хэндл держит сторонняя программа, которая создала файл.
(не удивляет, что он такой короткий?... - это просто тест чтобы как раз отбросить все другие возможности)
(не удивляет, что он такой короткий?... - это просто тест чтобы как раз отбросить все другие возможности)
У меня есть система, которая на основе этого компонента обрабатывает несколько тысяч файлов разом. Я вам в ТРЕТИЙ раз говорю (дальше буду капать в карму) - хэндл держит программа-постовщик файлов.
В тот момент, когда сторонняя программа выполняет CreateFile и только создает файл на диске, отрабатывает ваш обработчик fsw_Created и вы пытаетесь удалить его, но хэндл все еще занят. Нужно дождаться момента, когда хэндл будет освобожден и уже делать с файлом все что угодно.
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;
}
}
}
}
{
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);
}