2017-01-26 14 views
1

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

if (File.Exists(LogPath)) 
{ 
    File.Delete(LogPath); 
    File.Create(LogPath); 
} 

И я пишу в нем с помощью File.AppendAllText так:

File.AppendAllText(LogPath, logMessage); 

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

«так как он используется другим процессом»

Что не так с этим подходом?

+0

Два экземпляра программы работают одновременно? –

+0

- это единственный код, который влияет на файл, указанный в LogPath? Я бы ожидал ошибку с 'File.Delete (LogPath);' перед тем, как вы даже дойдете до 'File.AppendAllText (LogPath, logMessage);'. –

ответ

0

Вам нужно будет закрыть файл после создания для дальнейшей обработки.

if (File.Exists(LogPath)) 
{ 
    File.Delete(LogPath); 
    using(var handler = File.Create(LogPath)) 
    { 

    } 
} 

Другой способ может заключаться в использовании WriteAllText, и вам не нужно будет удалять его каждый раз.

File.WriteAllText(LogPath, "contents"); 
+1

'using (var handler = File.Create (LogPath)) {...}' лучший метод - не закрывайте 'IDisposable' (поток в контексте) вручную –

+0

OK @DmitryBychenko Я обновил его, спасибо:) –

3

Это не из-за File.AppendAllText, но вместо того, чтобы эта строка кода:

File.Create(LogPath); 

Как на the documentation of File.Create(string):

Возвращаемое значение
Тип: System.IO.FileStream
FileStream, который обеспечивает доступ для чтения/записи к файлу, указанному в пути.

Это возвращает открытый FileStream объект. Вы должны избавиться от этого объекта, чтобы закрыть поток и освободить файл. Если вы этого не сделаете, этот объект будет держать файл открытым до тех пор, пока GC не завершает работу объекта в какой-то более поздний неопределенный момент времени.

Вот как написать эту строку кода, либо один из следующих двух вариантов будет работать:

File.Create(LogPath).Dispose(); 
using (File.Create(LogPath)) { } 

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

Примечание: Если вы всегда вызов File.AppendAllText вы можете просто просто удалить его, так как AppendAllText создаст файл, если он уже не существует, так как в the documentation of File.AppendAllText:

Открывает файл, добавляет указанную строку в файл и затем закрывает файл. Если файл не существует, этот метод создает файл, записывает указанную строку в файл, а затем закрывает файл.

(курсив мой)

4

Это вызвано File.Create(). Удалите его, и File.AppendAllText создает новый файл, если он не существует.

Примечание:
File.Create() возвращает значение FileStream, если вы не выбрасывайте его, то это приведет к ошибке, если вы хотите получить к нему доступ.

+0

И причина, по которой ваш код работает в первый раз, но не второй, заключается в том, что вы не вводите предложение, в котором вызов 'create()' выполняется впервые. – arbitrarystringofletters

+0

Это кристально чистое, спасибо! – Toto

0

Вы, наверное, имели в виду

// clear the file (write an empty text to it) if it exists 
if (File.Exists(LogPath)) 
{ 
    File.WriteAllText(LogPath, ""); 
}  
...  
File.AppendAllText(LogPath, logMessage); 

вы можете попробовать комбинируя клиринг и записи в одном вызове:

File.WriteAllText(LogPath, logMessage); 

Если файл существует, то WriteAllText очистит его и писать logMessage; если файл не существует, WriteAllText создаст его и напишет logMessage.