c# - 从二进制日志文件读取,每12秒更新一次12k数据

时间:2009-07-23 09:03:47

标签: c# filestream binaryreader

我有一个二进制日志文件,其中包含来自传感器(Int16)的流数据 每隔6秒,就会添加6000个Int16类型的样本,直到传感器断开连接。

我需要定期轮询此文件,从上次位置读取继续。 是不是更好 a)保持文件流和二进制阅读器打开并在读数之间实例化 b)每次我需要读取时实例化文件流和二进制读取器(并保留一个外部变量来跟踪最后读取的位置) c)更好的东西?

编辑:到目前为止一些很棒的建议,需要补充一点,“服务器”应用程序由外部源供应商提供,无法修改。

5 个答案:

答案 0 :(得分:2)

如果它总是添加相同数量的数据,则重新打开它可能是有意义的。你可能想要在打开之前找出它的长度,然后向下舍入到可用的整个“样本集”,以防你在它仍然在写数据时捕获它。这可能意味着你阅读的内容少于可能读取的内容(如果你在检查长度和开始阅读之间完成了写操作),那么下次你就会赶上来。

您需要确保使用适当的共享选项,以便作者在您阅读时仍然可以写作。 (作者可能也必须考虑到这一点。)

答案 1 :(得分:2)

您可以使用MemoryMappedFiles吗?

如果可以,将文件映射到内存中并在进程之间共享,只需每次递增指针的偏移量,就可以读取数据。

如果您将其与活动结合使用,您可以在读取信息时向读者发出信号。没有必要阻止任何东西,因为读者总是会读取已经写过的“旧”数据。

答案 2 :(得分:2)

我建议使用管道,它们就像文件一样,除了直接在应用程序之间流数据,即使应用程序在不同的PC上运行(尽管如果你能够更改这两个应用程序,这只是一个选项)。在“System.IO.Pipes”命名空间下查看。

P.S。你可以使用“命名”管道('c'也支持管道,所以基本上任何一半不错的编程语言都应该能够实现它们)

答案 3 :(得分:1)

我认为(a)是最好的,因为:

  • 当前位置会在您阅读时递增,您无需担心将其存储在某处;
  • 你不需要打开它并寻求所需的位置(重新打开它应该慢得多,但保持打开状态会给OS提供一些我相信的优化提示)每次你进行轮询时都会这样做;
  • 我能想到的其他解决方案需要PInvokes来处理系统进程间同步原语。而且它们不会比框架中的文件操作更快。

您只需设置正确的FileShare标志:

仅举例:

服务器

using(var writer = new BinaryWriter(new FileStream(@"D:\testlog.log", FileMode.Append, FileAccess.Write, FileShare.Read)))
{
    int n;
    while(Int32.TryParse(Console.ReadLine(), out n))
    {
        writer.Write(n);
        writer.Flush(); // write cached bytes to file
    }
}

客户:

using (var reader = new BinaryReader(new FileStream(@"D:\testlog.log", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)))
{
    string s;
    while (Console.ReadLine() != "exit")
    {
        // allocate buffer for new ints
        Int32[] buffer = new Int32[(reader.BaseStream.Length - reader.BaseStream.Position) / sizeof(Int32)];

        Console.WriteLine("Stream length: {0}", reader.BaseStream.Length);
        Console.Write("Ints read: ");
        for (int i = 0; i < buffer.Length; i++)
        {
            buffer[i] = reader.ReadInt32();
            Console.Write((i == 0 ? "" : ", ") + buffer[i].ToString());
        }
        Console.WriteLine();
    }
}

答案 4 :(得分:0)

您也可以将数据流式传输到数据库中,而不是将文件作为另一种方式传输,然后您就不必担心文件锁定了。

但是如果您坚持使用文件方法,则可能需要在每次从中读取数据时关闭该文件;它取决于写入文件的过程有多复杂,以及它是否可以检测到文件锁定操作并做出适当的响应而不会崩溃。