2010-02-23 3 views
2

Я копирую с клиентского компьютера на серверный компьютер в общем каталоге. Мой сервер обнаруживает новый файл, и после завершения копирования он должен обработать его. Проблема заключается в том, что при написании большого файла и использовании FileSystemWatcher вы не обнаружите, выполнено ли копирование или нет. Единственный способ проверить это - попробовать открыть файл (File.OpenRead/OpenWrite) и получить исключение. Как я могу получить уведомление о том, что копия завершена, не прибегая к обработке исключений в качестве управления потоком?Как получить открытые дескрипторы записи в файле с помощью C#?

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

ответ

1

Вместо использования этого специального уведомления о опросе FileSystemWatcher, почему клиент не может явным образом уведомлять сервер по вызову службы WCF (или что-то еще)? Вы даже можете сделать простой EXE, который клиент вызвал NotifyServerFileUploaded.exe [name of file].

Таким образом, нет опроса, нет обмана рукоятки и нет проблем с перфорацией.

+0

Что делать, если на клиенте он использует проводник Windows, чтобы просто перетащить файл в общий сетевой ресурс? –

1

Скопируйте файл во временный файл. Когда копия будет завершена, переименуйте. Переименование является атомарным. Просто убедитесь, что серверный компьютер игнорирует временные файлы.

0

Повторите попытку файла для эксклюзивного чтения.

int maxRetry = 3; 
int x = 0; 
tryAgain: 
try 
{ 
    using (var fs = File.Open("file.txt", FileMode.Open, 
              FileAccess.Read, 
              FileShare.None)) 
    { 
     // you have exclusive read here 
    } 
} 
catch (IOException) 
{ 
    if (x++ > maxRetry) 
     throw; 
    Thread.Sleep(500); 
    goto tryAgain; 
} 
+0

Да ... если у вас есть фобия goto, вы можете использовать какое-то время или для. –

+0

(Я думаю, что IOException - это то, что бросается, когда у вас нет эксклюзивного доступа ... вам может понадобиться использовать другое исключение или просто перехватить исключение ... это зависит от вас) –

+0

да, это то, что у меня было в разум. Вот что я предложил в теме. Но я знаю, что бросать/ловить исключения, действует отвратно на приложение (сильно), и я не хочу, чтобы мое приложение продолжало ловить исключения. Я ищу другой путь вокруг него. – LolaRun

1

Вы пытались использовать FilesystemWatcher и созданное событие?

myWatcher.NotifyFilter = NotifyFilters.Attributes | NotifyFilters.FileName | NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.Security | NotifyFilters.Security | NotifyFilters.DirectoryName; 


myWatcher.Created += new FileSystemEventHandler(watcher_Changed);