Возникла проблема с открытием/записью текстового файла в ASP.NET.
-
11-07-2019 - |
Вопрос
Я хочу записывать статистику в текстовый файл каждый раз, когда человек загружает страницу.Но время от времени я получаю сообщение об ошибке типа «Не удалось открыть файл, уже используется».Я не могу на 100% повторить эту ошибку, она очень нестабильна.Мой код
Public Sub WriteStats(ByVal ad_id As Integer)
Dim ad_date As String = Now.Year & Now.Month
Dim FILENAME As String = Server.MapPath("text/BoxedAds.txt")
Dim objStreamWriter As StreamWriter
objStreamWriter = File.AppendText(FILENAME)
objStreamWriter.WriteLine(ad_id & ";" & ad_date)
objStreamWriter.Close()
End Sub
Мой вопрос: как я могу заблокировать и разблокировать файл, чтобы избежать случайных ошибок?
Спасибо
Решение
Вам придется обработать исключение и создать некоторую обработку, чтобы повторить попытку записи в файл через короткий случайный интервал.
Если у вас слишком много конфликтов, возможно, имеет смысл записать их в таблицу в базе данных и создать процесс для экспорта в файл (если он все еще необходим).
Другие советы
Если два или более запроса поступают на ваш веб-сервер примерно в одно и то же время, все они попытаются открыть один и тот же файл.Вам нужно будет создавать уникальные имена файлов для каждого запроса.
Public Sub WriteStats(ByVal ad_id As Integer)
Dim ad_date As String = Now.Year & Now.Month
Dim FILENAME As String = Server.MapPath("text/BoxedAds.txt")
Dim index As Integer
Using fs As New IO.FileStream(FILENAME, IO.FileMode.Append, IO.FileAccess.Write, IO.FileShare.ReadWrite), _
tl As New TextWriterTraceListener(fs)
index = Trace.Listeners.Add(tl)
Trace.WriteLine(ad_id & ";" & ad_date)
Trace.Listeners(index).Flush()
Trace.Flush()
End Using
Trace.Listeners.RemoveAt(index)
End Sub
Здесь три важные вещи:
- Использование IO.FileShare.ReadWrite для одновременной записи нескольких записей в файл.
- Оператор using, обеспечивающий немедленное закрытие потока даже в случае возникновения исключения.Это сведет к минимуму столкновения
- TextWriterTraceListener создаст для вас временный файл, если он не сможет открыть запрошенный вами файл, чтобы убедиться, что сообщение не потеряно.
У меня не было проблем с краткой информацией, используя:File.AppendAllText(путь, информация);
Что касается комментария о том, что он вызывает блокировки, то из отражателя он использует те же параметры, которые очень хорошо объяснил Джоэл.Он не использует средство записи трассировки, поэтому не будет выводить данные во временный файл в случае высокой нагрузки/большого содержимого, вызывающего проблемы.
Если информация большая, вам действительно нужны отдельные файлы.Для высокой нагрузки я бы последовал предложению Джоэла и создал временный файл, что альтернативно можно сделать, перехватив исключение в File.AppendAllText и используя тот же File.AppeandAllText с уникальным именем файла.