从C#中不断增长的文件中读取?

从C#中不断增长的文件中读取?,c#,.net,windows,streaming,filestream,C#,.net,Windows,Streaming,Filestream,在C#/.NET(在Windows上)中,有没有一种方法可以使用文件流读取“正在增长”的文件?打开filestream时,文件的长度将非常小,但该文件将由另一个线程写入。如果/当filestream“赶上”另一个线程时(即Read()返回读取的0字节),我想暂停以允许文件缓冲一点,然后继续读取 我真的不想使用FilesystemWatcher并继续创建新的文件流(正如针对日志文件所建议的那样),因为这不是日志文件(它是一个正在动态编码的视频文件),性能是一个问题 谢谢, Robert我解决这个问

在C#/.NET(在Windows上)中,有没有一种方法可以使用文件流读取“正在增长”的文件?打开filestream时,文件的长度将非常小,但该文件将由另一个线程写入。如果/当filestream“赶上”另一个线程时(即
Read()
返回读取的0字节),我想暂停以允许文件缓冲一点,然后继续读取

我真的不想使用
FilesystemWatcher
并继续创建新的文件流(正如针对日志文件所建议的那样),因为这不是日志文件(它是一个正在动态编码的视频文件),性能是一个问题

谢谢,

Robert

我解决这个问题的方法是使用/FilesystemWatcher类,当它在需要的文件上触发时,您可以打开一个文件流并将其读到最后。当我完成阅读时,我保存了读卡器的位置,所以下次/FilesystemWatcher触发时,我打开一个流,将位置设置为上次的位置

调用FileStream.length实际上非常慢,我的解决方案没有性能问题(我正在读取一个从10mb到50MB的“日志”)


对我来说,我描述的解决方案非常简单,易于维护,我会尝试并分析它。我认为你不会因此而受到任何性能问题。当ppl玩多线程游戏时,我会这样做,占用他们的整个CPU,没有人抱怨我的解析器比竞争对手的解析器要求更高。

你可以这样做,但你需要使用
Stream.Seek
并在线程之间进行适当的同步,仔细跟踪文件的读写位置。通常,您将使用<代码> EnviaWITHANDELE < /代码>或其子类对数据进行同步,并且还需要考虑对 FielestRAM对象本身的访问的同步(可能通过<代码>锁< /Cord>语句)。


更新:在回答问题时,我实现了类似的情况——在后台下载文件,同时上传文件。我使用了内存缓冲区,并发布了一个有工作代码的。(这是GPL,但对您来说可能并不重要-在任何情况下,您都可以使用这些原则来做自己的事情。)

另一件可能有用的事情是FileStream类上有一个名为ReadTimeOut的属性,该属性定义为:

获取或设置一个值(以毫秒为单位),该值确定流在超时之前尝试读取的时间。(从流继承)

这可能很有用,因为当读取赶上写入时,执行读取的线程可能会在写入缓冲区刷新时暂停。当然值得写一个小测试,看看这个属性是否对你的事业有任何帮助


读写操作是否发生在同一个对象上?如果是这样的话,您可以在文件上编写自己的抽象,然后编写跨线程通信代码,以便执行写操作的线程在完成时通知执行读操作的线程,以便执行读操作的线程在到达EOF时知道何时停止读操作。

这与文件周围的StreamReader一起工作,通过以下步骤:

  • 在写入文件的程序中,使用读共享打开文件,如下所示:

    var out = new StreamWriter(File.Open("logFile.txt",  FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read));
    
    using (FileStream fileStream = File.Open("logFile.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
    using ( var file = new StreamReader(fileStream))
    
  • 在读取文件的程序中,使用读写共享打开文件,如下所示:

    var out = new StreamWriter(File.Open("logFile.txt",  FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read));
    
    using (FileStream fileStream = File.Open("logFile.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
    using ( var file = new StreamReader(fileStream))
    
  • 在访问输入流之前,请检查是否已到达终点,如果已到达终点,请等待一段时间

    while (file.EndOfStream)
    {
        Thread.Sleep(5);
    }
    

  • 出于性能考虑,这个问题特别打折了使用观察程序的可能性。如果您所做的只是尽可能多地读取数据,然后等待更多数据,则不必在读取器中调用FileStream.Length。观察者触发的延迟是什么?这会随着机器负载的变化而变化吗?我现在就用这个,如果我以后需要做别的事情,我会的。我会研究这个。。。对于kicks,只需将编码结果写入内存(即使用双缓冲区),然后同时将其发送到网络和缓存文件是否更容易?如果在FileStream上设置ReadTimeOut引发异常,该答案如何获得+3s