1

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

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

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

这些是挑战:

  • 由于 Matlab 二进制文件需要信号头中的信号长度(以字节数给出),我需要知道正手的长度。或者,或者在最后返回写入的二进制文件并存储长度。
  • 性能需要非常好。Target 正在接近硬盘的 r/w 速度,因此 CPU 时间需要较低。
  • 由于数据不适合内部存储器,我需要一些分块处理。但是如何正确限制块大小,以便在不牺牲性能的同时不会出现内存溢出异常?

我已经尝试过要读取的文件的内存映射,但我坚持这一点,因为我需要沿着完整的文件搜索以了解信号的长度。

什么是完成上述工作的好方法?

4

2 回答 2

1

我会按顺序重复扫描整个输入文件。每次通过文件,我都会在内存中收集尽可能多的“信号”。一旦工作内存缓冲区已满,我会将收集到的“信号”写入输出 Matlab 文件并重新开始以在下一次通过时收集更多信号。一旦没有发现更多新信号,算法就会结束。

该算法需要对大文件的数据进行多次传递,但至少它是相当快的顺序 IO。

于 2012-06-15T11:46:59.883 回答
0

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

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

作为额外的奖励,您确实可以通过读取其文件长度来了解信号长度,或者如果您执行基于时间的工作,我会编写一个标题,其中包含在拆分过程中找到的最终信号长度。

于 2012-06-18T07:21:36.940 回答