Файл используется другим процессом в C#

Я пытаюсь удалить файл в C#, однако я получаю сообщение о том, что файл используется из другого процесса. Я хочу проверить, существуют ли файлы, и закрыть его. Я использую следующую функцию, чтобы проверить, открыт ли файл:

public static bool IsFileInUse(string path)
    {
        if (string.IsNullOrEmpty(path))
            throw new ArgumentException("'path' cannot be null or empty.", "path");

        try
        {
            using (var stream = new FileStream(path, FileMode.Open, FileAccess.Read)) { }
        }
        catch (IOException)
        {
            return true;
        }

        return false;
}

и я пытаюсь, когда файл используется, чтобы закрыть его:

bool checking = IsFileInUse(file );
File.Create(file ).Close();
if (File.Exists(file))
{
       File.Delete(file );
}

У меня есть проблемы в строке File.Create, я получаю сообщение:

Файл используется другим процессом.

РЕДАКТИРОВАТЬ: я пытаюсь использовать блокировку, чтобы удалить файл. Предполагается ли удалить файл внутри оператора блокировки? Как я могу правильно использовать оператор блокировки?

3 ответа

Решение

Почему вы полагаете, что операция чтения не удастся, если файл используется, а операция записи - нет? File.Create() потерпит неудачу точно так же, как новый FileStream() не удалось до...

См. Также IOException: процесс не может получить доступ к файлу "путь к файлу", поскольку он используется другим процессом.

Обратите внимание, что ваша проверка не будет выполнена, если другой процесс не открыл этот файл исключительно (проверьте FileShare перечисление): файл может быть открыт для совместного чтения, записи и иногда даже для удаления (например, вы можете читать одновременно, но не записывать, однако другой процесс может позволить вам удалить этот файл...).

Закрытие открытого файла может быть действительно разрушительным для другого процесса, он может завершиться сбоем, приятно обработать проблему или... что-нибудь еще (игнорировать эту ошибку и произвести случайный вывод, снова открыть файл и т. Д.) можно сделать это в C#? Да, с некоторым P / Invoke...

1) Давайте найдем дескриптор файла, который вы хотите разблокировать. использование NtQuerySystemInformation() и перечислять все дескрипторы, пока не найдете тот, который ссылается на этот файл.

2) Дублируйте этот дескриптор, чтобы он действовал в вашем собственном процессе, используя DuplicateHandle(),

3) Закрыть, просто создать указатель DUPLICATE_CLOSE_SOURCE, он закроет и ваш дескриптор, и оригинальный (конечно, если у вашего процесса достаточно прав).

4) Проверьте, действительно ли файл закрыт NtQuerySystemInformation() опять же, если нет, то вам может потребоваться непосредственно закрыть родительский процесс.

В вашем коде вы ничего не делаете с результатом IsFileInUse.

это File.Create(file ).Close(); также не закроет файл, открытый другим процессом. Вам необходимо закрыть процесс, в котором открыт файл, и, если это ваше собственное приложение, закрыть дескриптор файла, прежде чем пытаться удалить файл.

bool checking = IsFileInUse(file );
File.Create(file ).Close();
if (!checking) 
{
     if (File.Exists(file))
     {
            File.Delete(file );
     }
}

Вам не нужно проверять, существует ли файл, просто попробуйте удалить его:

https://msdn.microsoft.com/en-us/library/system.io.file.delete(v=vs.110).aspx

Если удаляемый файл не существует, исключение не выдается.

Попробуйте и проверьте исключение

  try {
    File.Delete(file);
  }
  catch (IOException) {
    // File in use and can't be deleted; no permission etc.
  }
Другие вопросы по тегам