在 C#/.NET(在 Windows 上)中,有没有一种方法可以使用文件流来读取“正在增长的”文件?打开文件流时文件的长度会非常小,但文件将被另一个线程写入。如果/当文件流“赶上”到另一个线程(即当Read()
返回 0 字节读取时),我想暂停以允许文件缓冲一点,然后继续阅读。
我真的不想使用FilesystemWatcher
并继续创建新的文件流(如对日志文件的建议),因为这不是日志文件(它是动态编码的视频文件)并且性能是一个问题。
谢谢,
罗伯特
在 C#/.NET(在 Windows 上)中,有没有一种方法可以使用文件流来读取“正在增长的”文件?打开文件流时文件的长度会非常小,但文件将被另一个线程写入。如果/当文件流“赶上”到另一个线程(即当Read()
返回 0 字节读取时),我想暂停以允许文件缓冲一点,然后继续阅读。
我真的不想使用FilesystemWatcher
并继续创建新的文件流(如对日志文件的建议),因为这不是日志文件(它是动态编码的视频文件)并且性能是一个问题。
谢谢,
罗伯特
这与围绕文件的 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))
Before accessing the input stream, check whether the end has been reached, and if so, wait around a while.
while (file.EndOfStream)
{
Thread.Sleep(5);
}
我解决这个问题的方法是使用DirectoryWatcher / FilesystemWatcher 类,当它触发文件时,你希望你打开一个 FileStream 并将其读到最后。当我完成阅读时,我保存了阅读器的位置,所以下次DirectoryWatcher / FilesystemWatcher 触发器我打开一个流时,将位置设置为我上次所在的位置。
调用 FileStream.length 实际上非常慢,我的解决方案没有性能问题(我正在阅读从 10mb 到 50 ish 的“日志”)。
对我来说,我描述的解决方案非常简单且易于维护,我会尝试并对其进行分析。我认为您不会因此而遇到任何性能问题。当人们玩多线程游戏时,我会这样做,占用他们的整个 CPU 并且没有人抱怨我的解析器比竞争的解析器要求更高。
可能有用的另一件事是 FileStream 类有一个名为 ReadTimeOut 的属性,其定义为:
获取或设置一个值(以毫秒为单位),该值确定流在超时之前尝试读取的时间。(继承自流)
这可能很有用,因为当您的读取赶上您的写入时,执行读取的线程可能会在写入缓冲区被刷新时暂停。确实值得编写一个小测试,看看这个属性是否会以任何方式帮助您的事业。
读写操作是否发生在同一个对象上?如果是这样,您可以在文件上编写自己的抽象,然后编写跨线程通信代码,以便执行写入的线程并在完成时通知执行读取的线程,以便执行读取的线程知道何时停止读取当它到达EOF时。