2010-09-07 4 views
3

Я открываю файл с доступом для чтения и разрешаю последующее чтение | write | удалить доступ к файлу общего доступа к файлу (хвост файла). Если файл удален во время обработки, есть способ обнаружить, что файл ожидает удаления (см. Раздел «Файлы» http://msdn.microsoft.com/en-us/library/aa363858(v=VS.85).aspx)? Если какой-то внешний процесс (процесс владения) выпустил удаление, я хочу как можно скорее закрыть мой дескриптор, чтобы разрешить удаление файла, чтобы не мешать какой-либо логике процесса владения.Обнаружение удаления файла в открытом файле

Я нахожусь на C# и не вижу способа обнаружения ожидающего удаления. Файл был открыт с использованием объекта FileStream. Есть ли способ обнаружения удаления в C# или в некоторых других функциях Windows?

+0

Следует упомянуть, что вы используете DELETE_ON_CLOSE/FILE_SHARE_DELETE. Я сомневаюсь, что это очень распространенное использование. – 2010-09-07 22:56:56

ответ

0

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

Единственное «решение» в пределах этих границ, о которых я могу думать, это опрос по доступу к файлу и проверить исключение (если есть), вы вернетесь. Возможно, есть что-то гораздо более сложное (на более низком уровне, чем win32-файл API?!?), Но это уже идет по пути «uhg» :-)

+1

Я принимаю это как ответ, поскольку это все, что я мог сделать. Имея открытый дескриптор файла, каждый раз, когда мне нужно возвращаться и читать из дескриптора, я также пытаюсь открыть файл снова. Если я вернусь к UnauthorizedAccessException (см. Msdn), то я ПРИНИМАЮ, что файл был удален и закрыл мой дескриптор. Я уверен, что это дорого, но я ничего не мог придумать. –

0

FileSystemWatcher, вероятно, будет самым близким, но он не сможет обнаружить «ожидающее» удаление; когда файл IS удален, в FileSystemWatcher будет создано событие, и вы можете подключить обработчик, который изящно прервет обработку вашего файла. Если блокировка (или отсутствие одного), которую вы получаете при открытии файла, позволяет вообще удалить файл, просто закрывая только FileStream только для чтения, когда это произойдет, не должно влиять на файловую систему.

Основные шаги наблюдателя файлов - создать его, передав экземпляр объекта FileInfo в конструктор. FileInfos можно создавать недорого, просто создавая экземпляр, передавая ему путь и имя файла в виде строки. Затем установите для NotifyFilter тип (ы) модификаций файловой системы, которые вы хотите посмотреть в этом файле. Наконец, присоедините обработчик событий вашего процесса к событию OnDeleted. Этот обработчик событий, вероятно, может быть таким же простым, как установить бит-флаг где-нибудь, что ваш основной процесс может прочитать, и закрыть FileStream. Затем вы получите исключение при следующей попытке работать с потоком; поймать его, прочитать флаг, и если он установлен, просто изящно прекратите делать файлы. Вы также можете поместить обработку файла в отдельный рабочий поток, и обработчик события может просто сказать, что поток умеет в грациозном методе.

+0

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

+1

Это не возможно афайк. Удалить не удастся - то, что вы действительно просите, - это способ обнаружить желание удалить в другом процессе.Практически невозможно реализовать средства в ОС, чтобы уведомить всех пользователей текущего файла о том, что какой-либо другой процесс пытается удалить файл, который используется, до удаления, пока другие пользователи не захотят закрыть их использование (что, если они откажутся?). Что, если процесс удаления после этого меняет свое мнение или выходит по какой-то причине? Взаимодействия слишком ужасны для размышлений. –

+0

Вы говорите, что запрос владельца процесса на удаление файла не удастся? Если это так, это неверно. Удаление завершается успешно, и файл ожидает удаления до тех пор, пока все дескрипторы не будут закрыты. Как только ручки не открываются, файл удаляется. Во время ожидающего удаления последующие запросы на доступ к файлу получают исключение, исключающее доступ. См. Http://msdn.microsoft.com/en-us/library/aa363915(v=VS.85).aspx или http://msdn.microsoft.com/en-us/library/aa363858(v=VS +0,85) .aspx. –

0

Если файл достаточно мал, ваше приложение может обрабатывать копию файла, а не сам файл. Кроме того, если вашему приложению необходимо знать, удалил ли процесс владения исходный файл, настройте файл FileSystemWatcher (FSW) в файле. Когда файл исчезнет, ​​FSW может установить флаг для обработки прерываний:

private bool _fileExists = true; 

public void Process(string pathToOriginalFile, string pathToCopy) 
{ 
    File.Copy(pathToOriginalFile, pathToCopy); 

    FileSystemWatcher watcher = new FileSystemWatcher(); 
    watcher.Path = pathToOriginalFile; 
    watcher.Deleted += new FileSystemEventHandler(OnFileDeleted); 

    bool doneProcessing = false; 
    watcher.EnableRaisingEvents = true; 

    while(_fileExists && !doneProcessing) 
    { 
     // process the copy here 
    } 

    ... 
} 

private void OnFileDeleted(object source, FileSystemEventArgs e) 
{ 
    _fileExists = false; 
} 
+0

Опять же, FileSystemWatcher не будет работать, потому что файл не удаляется, пока все дескрипторы файла не будут закрыты. Поскольку у меня есть дескриптор файла, он ожидает удаления, пока я не закрою свой дескриптор. –

+0

После того, как вы сделаете копию файла, вы отпустите дескриптор исходного файла. И если я не ошибаюсь, FSW будет иметь дескриптор _directory_, в котором находится файл, а не дескриптор файла. – 2010-09-08 18:30:33

+0

Вы правы, я должен прочитать ваш ответ немного ближе. Эти файлы потенциально могут быть любого размера, хотя и обработка копии не была бы осуществима во всех случаях. –

0

Нет, нет чистого способа сделать это. Если вас беспокоили другие процессы, открывающие и/или изменяющие файл, то oplocks могли бы вам помочь. Но если вы просто ищете уведомление о том, когда удаленное удаление будет удалено, нет простого способа сделать это (без создания фильтра файловой системы, подключения API-интерфейсов и т. Д., Все из которых жутки для приложения делайте это без уважительной причины).