【问题标题】:Having problem opening/writing to a text file in ASP.NET在 ASP.NET 中打开/写入文本文件时出现问题
【发布时间】:2010-10-12 23:16:18
【问题描述】:

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

我的问题是,我怎样才能锁定和解锁文件,以免出现不稳定的错误?

谢谢

【问题讨论】:

    标签: asp.net vb.net streamwriter


    【解决方案1】:

    如果两个或多个请求大致同时访问您的网络服务器,它们都会尝试打开同一个文件。您需要为每个请求创建唯一的文件名。

    【讨论】:

    • 其实:每个会话可能已经足够好了。单个用户不太可能同时创建这么多请求。
    【解决方案2】:

    您必须处理异常并构建一些处理程序,以便在短暂的随机间隔后重新尝试写入文件。

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

    【讨论】:

    • 我有时需要每页最多写入 20 次文件,这会对数据库造成多大的压力?
    【解决方案3】:

    我在使用简短信息时没有遇到任何问题: File.AppendAllText(路径,信息);

    关于它导致锁定的评论,从反射器来看,它使用了 Joel 很好解释的相同选项。它不使用trace writer,所以在高负载/大内容造成麻烦的情况下不会输出到临时文件。

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

    【讨论】:

    • 还能锁:我见过。
    • 你确定吗,这是在生产中,而不是一个单独的日志条目......正如我所说的,一小部分信息
    • @Joel 我确认它使用了适当的反射器选项,你的意思是你的解决方案也锁定了吗? (不要这么认为,正如我所说的生产中没有日志条目)
    • @Joel,如果它被锁定,我没有注意到您使用生成临时文件的跟踪器,更新了我的答案。
    【解决方案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. 使用语句确保流立即关闭,即使发生异常也是如此。这将最大限度地减少碰撞
    3. 如果 TextWriterTraceListener 无法打开您请求的文件,它将为您创建一个临时文件,以确保消息不会丢失。

    【讨论】:

    • 乔尔,当简单的 File.AppendAllText 完全做到这一点时,无需使用自定义解决方案(检查反射器)
    • 我必须这样做,但正如我上面所说:我已经看到 File.AppendAllText 获得锁定。
    • 那么您的解决方案也是如此,我想我们需要一个替代解决方案/我的看法是,无论采用何种方法,它都会给负载带来麻烦
    • 嗯,nvm,重新阅读您的答案,如果打开文件失败,则没有注意到您对使用临时文件的 TextWriterTraceListener 的评论
    • 是的,我稍后补充了一点:我仍然有文件被锁定的代码,并返回参考我们如何解决它。
    猜你喜欢
    • 2014-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-04
    • 1970-01-01
    • 1970-01-01
    • 2010-10-21
    相关资源
    最近更新 更多