【问题标题】:Overwrite text file that is in use by another process?覆盖另一个进程正在使用的文本文件?
【发布时间】:2011-05-23 05:21:48
【问题描述】:

我有一个已打开并被另一个程序使用的日志文件,我使用以下内容读取了它的内容:

    Dim strContents As String
    Dim x As New FileStream(FullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
    Dim objReader As StreamReader
    objReader = New StreamReader(x)
    strContents = objReader.ReadToEnd()
    objReader.Close()

这适用于在其他程序仍在使用文件时从文件中读取文本,但是,在此之后我需要立即截断文本文件(不删除它),使其再次为空白。但该文件仍将被其他程序使用。

我试过了

    Dim sWrite As StreamWriter
    sWrite = New System.IO.StreamWriter(FullPath, False)
    sWrite.Write("")
    sWrite.Close()

但我得到“正在被另一个应用程序使用”异常。我试过查看 StackOverflow 和谷歌搜索,但我似乎找不到答案,我也找不到使用文件流执行此操作的方法,或者我会尝试使用

Dim fs As New FileStream(FullPath, FileMode.Open, FileAccess.Write, FileShare.ReadWrite)

提前致谢。

【问题讨论】:

    标签: c# .net vb.net file process


    【解决方案1】:

    那是因为其他程序锁定了文件,操作系统不会让你做你想做的事。除非您将其他程序更改为不锁定写入。

    【讨论】:

      【解决方案2】:

      不幸的是,无论使用哪种语言,问题的解决方案都不是简单地添加或修改几行代码。您正在描述resource contention 的经典示例。

      这种类型的问题最好使用访问管理器来解决,即另一个仲裁写入的进程,这样您的程序就不会覆盖另一个程序所做的事情,反之亦然。

      【讨论】:

      • 记录的程序实际上每 3-5 分钟写入一次数据,我试图在这些写入之间从日志中清除数据,只是因为程序执行记录不会释放它在写入之间对文本文件的锁定。如果我在写作过程中清除它,我会得到奇怪的数据。
      • 您可以控制其他程序吗?如果你可以用任何方式修改它并且保证两个程序之间的同步,在每次写入后将其Close()文件。
      • 否定,我无法控制其他程序。
      • 哎哟!然后,您必须使用 Event Logging API。见codeproject.com/KB/cs/WriteEventLog.aspx
      【解决方案3】:

      在其他进程关闭流之前,我不确定您是否可以这样做。但是,您可以终止正在写入文件的进程。

      这是一个例子。

      Dim pProcess() As Process = System.Diagnostics.Process.GetProcessesByName("notepad")
      
      For Each p As Process In pProcess
          p.Kill()
      Next
      

      看看这个:http://vbnetsample.blogspot.com/2007/08/start-and-kill-process.html

      【讨论】:

      • 这会阻止记录器并破坏目的,不过谢谢。
      【解决方案4】:

      关于这个主题还有很多其他帖子。

      Detecting whether a file is locked by another process (or indeed the same process)

      How to check for file lock?

      Can I simply 'read' a file that is in use?

      解决方案似乎是:

      Try
      'Code to read file if its not locked by another app
      Catch as System.IO.IOException
      

      也只是一个仅供参考,您的日志文件是非托管资源,因此确定性最终确定将有助于解决此资源争用问题。使用 Using 语句进行确定性终结,例如:

      Using fs = New FileStream(path, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite)
          fs.SetLength(0)
          file.Save(fs)
          fs.Flush()
      End Using
      

      【讨论】:

      • 我有一个写入日志文件的预定进程。如果有人登录服务器并让文件资源管理器处于打开状态,并且选择了该日志文件,则计划进程会收到此异常并且无法运行,或者无法写入其日志文件。很烦人。文件资源管理器应该打开文件,显示预览,然后关闭它;但不,只要文件被选中,它就会保持文件打开。我无法从计划的进程中终止文件资源管理器,这样做会产生一个糟糕的问题。
      猜你喜欢
      • 1970-01-01
      • 2012-07-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-13
      相关资源
      最近更新 更多