关于“冲突”二进制格式的快速二进制读写问题

时间:2012-06-15 11:42:35

标签: c# matlab file-io binary memory-mapping

我正在努力处理二进制(文件)数据(在c#中)。情况就是这样:

  • 我有一个二进制文件,可以小到1 MB,大到60 GB,因此不可能适合内存(假设2 GB内存的慢速笔记本电脑,都运行32位和64位窗口)。该文件包含来自例如时基的20个源的数据。文件的标题没有告诉我信号的长度,这意味着每个信号的长度可以(并且大部分都是)会有所不同。因此,我不知道一个信号在正手上包含的字节数。另请注意,数据沿文件间距不均匀。因此,我必须在文件中搜索与相应信号样本匹配的标识符(2个字节)。

  • 其次,我需要处理并将此数据存储在新的二进制文件中。文件大小大致相同。但二进制格式完全不同。实际上它是一个Matlab二进制文件格式。

这些是挑战:

  • 由于Matlab二进制文件需要信号头中的信号长度(以字节数给出),我需要知道正手的长度。或者,或者在末尾回写书面二进制文件,然后存储长度。
  • 表现必须非常好。目标正在接近硬盘的r / w速度,因此CPU时间需要很低。
  • 由于数据不适合内部存储器,我需要进行一些分块处理。但是如何正确地限制块大小以便我不会在没有同时牺牲性能的情况下获得内存溢出异常?

我已经尝试过要读取的文件的内存映射,但我坚持这个,因为我需要沿着整个文件搜索才能知道信号的长度。

实现上述目标的好方法是什么?

2 个答案:

答案 0 :(得分:1)

我会反复扫描整个输入文件。每次通过文件,我会在内存中收集尽可能多的“信号”,因为内存可以容纳。一旦工作内存缓冲区已满,我会将收集的“信号”写入输出Matlab文件,然后再次开始收集下一遍的更多信号。一旦找不到新的信号,算法就会结束。

这个算法需要多次传递大文件的数据,但至少它是顺序IO,速度相当快。

答案 1 :(得分:0)

信号分配器怎么样?我会扫描一次文件并为每个新信号创建一个新文件。在读取大文件时,我会将数据写入正确的信号文件。内存是一个非问题,因为你总是只从磁盘读取一个块(大约4KB),这不会让你知道任何内存边界。

如果您需要在信号之间进行某种关联,则需要在分割文件中插入一些时间点标记,以便基于时间进行分析。这应该也很容易做到。

作为附加奖励,您可以通过读取文件长度知道信号长度,或者如果您使用基于时间的东西,我会写一个标题,其中包含在分割过程中找到的最终信号长度。