2011-12-29 3 views
4

Моя программа создает файл журнала при его запуске. Пользователь имеет возможность с помощью настроек «очистить журнал», который вызывает метод для удаления файла журнала.Почему я не могу создать txt-файл после его удаления?

 //calls for a YesNo prompt to delete log or not 
     result = objectMessageBox.ReturnDeleteLogPrompt(); 

     if (result == DialogResult.Yes) 
     { 
      //throw prompt 
      if (File.Exists(objectLog.GetLogLocation()) == true) 
      { 
       try 
       {       
        //delete the log file 
        File.Delete(objectLog.GetLogLocation());       

        //throw balloon tip saying log was cleared 
        ShowBalloonTip("LogCleared"); 
       } 
       catch (Exception ee) 
       { 
        MessageBox.Show("Error thrown deleting log: " + ee); 
        System.Windows.Forms.Clipboard.SetText(ee.ToString()); 
       } 
      } 
     } 

Поскольку я полностью удалил файл журнала, мне необходимо его воссоздать. Поэтому я называю метод, который имеет это:

try 
     { 
      //we create a new log file so it seems that the log has just been cleared 
      objectLog.CreateLog(); 
     } 
     catch (Exception ee) 
     { 
      MessageBox.Show("Error occured while clearing log:\n" + ee); 
     } 

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

«System.IO.IOException: Процесс не может получить доступ к file '~~', потому что он используется другим процессом. "

Похоже, что во время моего вызова, чтобы удалить файл, он продолжает обращаться к нему? Нужно ли мне что-то утилизировать, когда я вызываю file.delete?

+0

Что такое трассировка стека? – SLaks

+0

Вы пробовали вызов dispose на objectLog после его удаления? –

+0

Вы уверены, что на самом деле нет другого приложения, в котором открыт файл журнала? Попробуйте использовать procmon и procexp из http://live.sysinternals.com/, чтобы проверить, какие приложения имеют доступ к файлу. –

ответ

3

Вместо того, чтобы удалять и воссоздавать один и тот же файл, вы можете просто очистить его?

Что-то, как это должно работать для вас:

FileStream f = File.Open(@[filename], FileMode.Create); 
f.Close(); 
+0

Это не отвечает на вопрос, как это делали другие, однако это помогло мне решить проблему. Спасибо. –

+0

В действительности FileMode.Create перезаписывает существующий файл новым, поэтому вы можете утверждать, что он обрабатывает удаление и отдых за один шаг. Но я понимаю, что вам интересно, почему файл по-прежнему заблокирован после .Delete и как долго. Это решение я должен оставить другим. Рад помочь вам решить вашу ближайшую проблему. – nycdan

0

Вы можете использовать System.IO.FileInfo.Delete удалить файл, а затем System.IO.FileInfo.Refresh(), прежде чем снова создания файла , Обновление должно прекратить исключение при повторном создании файла. Или, как говорит nycdan, используйте перечисление FileMode.Create.

+0

Неверно; 'Refresh()' не будет иметь никакого значения. 'Refresh()' просто повторно проверяет свойства в экземпляре 'FileInfo'. – SLaks

6

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

  • Операция удаления еще продолжается от операционной системы
  • Антивирусная программа или аналогичная функция безопасности открыли файл в ответ на его удаление, для предварительного удаления
  • Антивирусная программа или аналогичная функция безопасности уже открыли файл во время его использования и по-прежнему в процессе ответа на ваш запрос на удаление

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

Другими словами, график был следующим:

  • hg.exe экземпляр # 1 запускается, блокирует хранилище, создавая временный файл
  • hg.exe делает то, что ему нужно сделать
  • hg.exe удаляет файл, затем выходит
  • hg.ехе экземпляр # 2 запускается, пытается заблокировать хранилище, терпит неудачу, потому что файл используется

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

+0

Я никогда не замечал «FileShare.Delete» «Позволяет впоследствии удалить файл», прежде чем я заметил это сообщение :) С http://msdn.microsoft.com/en-us/library/windows/desktop/aa363915(v= vs.85) .aspx: «удаление файла не происходит до тех пор, пока последний дескриптор файла не будет закрыт». –

4

Там уже является признанным ответ, но, возможно, кто-то считает, что это полезно (или смеяться над ним, если я снова упустил что-то очевидное и впустую мое время полностью)

У меня создалось впечатление, что File.Delete будет либо удалить файл и затем верните или иным образом создайте исключение - пока я не прочитаю этот поток.

В API Windows упоминается, что при вызове DeleteFile файл «помечен для удаления при закрытии», так как он позволяет вызывать удаление в открытом файле. После того, как файл будет помечен для удаления, попытка его открытия завершится с ошибкой «Отказано в доступе». Когда последний дескриптор для этого файла закрыт, файл фактически удаляется.

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

using (File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Delete)) 
{ 
    File.Delete(path); 
} 

File.Open провалится, если другие в настоящее время файл открыт.

Обратите внимание на разницу здесь, что File.Delete даже удается, если файл не существует (если каталог не существует).

+0

Это очень интересно. Я буду голосовать, потому что я не знаю, достаточно ли звучит, чтобы быть выбранным ответом. Хотя я позволю другим перезвонить. –

Смежные вопросы