在ASP.NET中打开/写入文本文件时出现问题

时间:2009-03-12 16:21:31

标签: asp.net vb.net streamwriter

我想在每次加载页面时向文本文件写一些统计信息。但每隔一段时间我就会遇到“无法打开文件,已经在使用中”的错误类型。我无法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

我的问题是,如何锁定和解锁文件,以便我不再获得不稳定的错误?

由于

4 个答案:

答案 0 :(得分:4)

如果两个或多个请求几乎同时点击您的Web服务器,他们都会尝试打开同一个文件。您需要为每个请求创建唯一的文件名。

答案 1 :(得分:4)

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

这里有三件重要的事情:

  1. 使用IO.FileShare.ReadWrite一次允许文件上的多个编写者。
  2. 使用using语句确保即使发生异常也立即关闭流。这将最大限度地减少碰撞
  3. TextWriterTraceListener将为您创建一个临时文件,如果它无法打开您请求的文件,以确保邮件不会丢失。

答案 2 :(得分:1)

您将不得不处理异常并构建一些处理以在短暂的随机间隔后重新尝试写入文件。

如果你得到太多的争用,那么将它记录到数据库中的表并创建一个导出到文件的进程(如果仍需要它)可能更有意义

答案 3 :(得分:0)

我使用以下短信息时没有遇到任何问题: File.AppendAllText(path,info);

关于它引起锁定的评论,来自反射器它使用了Joel非常好地解释的相同选项。它不使用跟踪编写器,因此在高负载/大内容导致故障的情况下它不会输出到临时文件。

如果信息很大,你真的想要单独的文件。对于高负载,我会使用Joel的建议并创建一个临时文件,也可以通过捕获File.AppendAllText上的异常,并使用具有唯一文件名的相同File.AppeandAllText来完成。