Как проверить, будет ли File.Delete () успешным, не пытаясь это сделать, в C #? - PullRequest
30 голосов
/ 18 сентября 2009

В C # System.IO.File.Delete (filePath) либо удалит указанный файл, либо вызовет исключение. Если текущий пользователь не имеет разрешения на удаление файла, он вызовет исключение UnauthorizedAccessException.

Есть ли какой-нибудь способ, которым я могу заранее сказать, может ли удаление вызвать UnauthorizedAccessException или нет (то есть запросить ACL, чтобы узнать, имеет ли удостоверение текущего потока разрешение на удаление указанного файла?)

Я в основном хочу сделать:

if (FileIsDeletableByCurrentUser(filePath)) {
    /* remove supporting database records, etc. here */
    File.Delete(filePath);
}

но я понятия не имею, как реализовать FileIsDeletableByCurrentUser ().

Ответы [ 8 ]

17 голосов
/ 18 сентября 2009

Проблема с реализацией FileIsDeletableByCurrentUser заключается в том, что это невозможно сделать. Причина в том, что файловая система постоянно меняется.

Между любой проверкой файловой системы и следующей операцией может произойти и произойдет любое количество событий. В том числе ...

  • Разрешения на файл могут измениться
  • Файл может быть удален
  • Файл может быть заблокирован другим пользователем / процессом
  • USB-ключ, на котором находится файл, может быть удален

Лучшая функция, которую вы могли бы написать, была бы наиболее точно названа FileWasDeletableByCurrentUser.

11 голосов
/ 18 сентября 2009

Взгляните на эту статью - http://www.codeproject.com/KB/files/UserFileAccessRights.aspx

8 голосов
/ 18 сентября 2009

Вы пробовали System.IO.File.GetAccessControl (имя файла) он должен вернуть FileSecurity с информацией о разрешениях для этого файла.

2 голосов
/ 18 сентября 2009

Строго говоря, исключение UnauthorizedAccessException означает, что путь является каталогом, поэтому вы можете использовать команду типа System.IO.Path.GetFileName (path) и перехватить исключение аргумента.

Но если вы хотите более целостное решение, используйте System.IO.File.GetAccessControl, как упомянуто Дейлом Холливелом

1 голос
/ 18 сентября 2009

Как указано выше. Найдите файл разрешений и сравните его с пользователем, который запускает приложение.

Вы также всегда можете использовать этот подход

bool deletemyfile()  
{  
    try  
    {  
        ...delete my file  
        return true;  
    }  
    catch  
    {  
        return false;  
    }  
}

если он возвращает false, вы знаете, что он потерпел неудачу, если он возвращает true, то ... это сработало, и файл исчез. Не уверен, что именно вы ищете, но это было лучшее, что я мог придумать

0 голосов
/ 18 сентября 2009

Похоже, было бы проще делать вещи в следующем порядке:

  1. Получите всю необходимую информацию о файле для выполнения других частей (удаления данных базы данных и т. Д.)
  2. Попробуйте удалить файл
  3. Если вы успешно удалили файл, то выполните остальную часть «очистки». Если вы не удалили его успешно, верните / обработайте исключение и т. Д.
0 голосов
/ 18 сентября 2009

Вы должны получить список контроля доступа (ACL) этого файла.

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

0 голосов
/ 18 сентября 2009

Конечно, вы можете проверять флаги ReadOnly, используя System.IO и, возможно, безопасность ACL для файла в сочетании с текущим пользователем, но, как пишет Мерадад в своем комментарии, это никогда не будет полным доказательством во всех случаях. Таким образом, вам потребуется обработка исключений для исключительного случая в любое время (даже если это просто верхний уровень общего охвата , который регистрирует / показывает «непредвиденную проблему» и убивает ваше приложение).

...