【问题标题】:Reading large binary files读取大型二进制文件
【发布时间】:2014-04-22 06:14:32
【问题描述】:

我正在做一个项目,我将一些信号(一维数组)记录到二进制文件中。我可以存储大量数据(通常是几个千兆字节)。现在我想重新加载这些文件。

我有两个视觉组件。一个称为概述,另一个只是一个普通的 Y/T 图表。概述应该让用户了解完整文件(大文件)中的内容,而图表仅显示文件的一部分,通常是在概述中选择的具有可调整大小的矩形/带的部分。

因为文件可能非常大,加载到内存根本不是最佳的,所以主要想法是仅将重要数据/可见数据加载到内存(最大几 MB)。因此加载和显示是根据用户需求完成的。如果用户放大图表,则需要使用文件中的更多数据点重新加载数据。

我的问题是如何绘制概览组件以最佳方式显示文件的全部内容(而不是真正从文件中加载所有样本)。假设我的文件大于 10GB,我想让用户了解文件中的内容,但我可以绘制最大值。概述组件上有 16k 个样本?

是否有任何方法可以在日志记录期间存储任何其他数据(如索引、较小的数据块、图像...)以供以后加载和绘制概览组件?目前我只存储样本,但添加其他数据不会有问题。您对此有什么经验以及您是如何做到的?

了解我在做什么:

【问题讨论】:

  • 我真的不明白这个问题。只读取文件的一部分很容易。
  • 文件中有大量样本。对于概述,我需要显示完整的文件,但加载完整的文件是没有意义的,而我无法在屏幕上显示所有数据,但我仍然必须向用户概述文件中的内容。对于图表部分,我仅显示/加载用户在带有红色矩形的概览窗口中选择的文件的一部分。然而,“最坏”的情况是选择完整的概览窗口,这意味着我必须重新加载完整的文件,但我又不能这样做......只是每第 N 个样本。我希望我能解释清楚。
  • 并非如此。听起来很模糊。
  • 假设我有一个超过 10G 样本的大文件。为了概述,我必须虚拟显示所有这些 10GB 样本,但有两件事需要考虑。首先是我不能只将所有样本加载到内存中,其次是在屏幕上绘制 10GB 点根本没有效率。基本上我必须绘制文件的波形,但我不需要所有数据,因为它只是一个概述。所以我必须将所有这些 10GB 虚拟地填充到 16kSamples 的概览缓冲区中。那么如何画出这样的波形呢?
  • "一些信号(一维数组)" 这不是太多的信息。答案很大程度上取决于文件的结构。请更详细地描述它(示例),或者如果尚未确定,请描述文件结构应具有的要求。

标签: delphi delphi-2010 c++builder binaryfiles binary-data


【解决方案1】:

您可以使用多级抽取 - 只需存储每第 N 个、第 N^2 个等样本(例如,第 10、100、1000、10000...)。当用户改变窗口大小时,选择合适的级别,在这个窗口中包含大约 1000 个样本,快速加载并显示这些样本(1000 个点对于屏幕上的图表来说只是合理的数字)。

如果您的数据有一些特征、特殊属性,可以得到更大(升级)的数据集并应用Douglas-Peucker折线简化算法来保留这些特征。

【讨论】:

  • 为什么选择 10 作为基础?
  • 这是有道理的。我现在有了主意。也许我在抽取中看到的唯一问题是信号应该适用于奈奎斯特定理,并且很可能我应该进行一些过滤以避免抗锯齿。这基本上是一个重采样。我会这样看,听起来很有希望,也很有意义。我听说过 Douglas-Peucker 算法,但我从未想过它。处理大数据并提取有用信息是一个相当大的挑战。感谢您的想法
  • @David 10 只是示例。
  • 我查看了 Audacity 源代码,他们正在对波形文件进行某种缓存。他们仅在必要时(放大时)绘制所有点。我仍然需要更深入地挖掘以获得更多信息,但我明白了基本的想法。
  • 根据数据,您可能希望获得多个样本的平均值或平均值以显示缩小的部分。
【解决方案2】:

当我写入文件时,我会写入几个固定大小的数据块(取决于 DAQ 采样率)。在写入这些块的固定计数后,我添加一个统计块,其中包含有关已写入多少数据块以及从所有写入数据块一起计算的最大值、最小值、平均值和方差的信息。然后我重复它......直到用户停止录制。

File struct is:

[File header]
[DataChunk1]
[DataChunk2]
...
[DataChunkN]
[StatsChunk1]
[DataChunkN+1]
[DataChunkN+2]
...
[DataChunkN+..]
[StatsChunk2]
....

当我想加载文件并绘制数据时,我只是重新计算我当前在图表上设置的数据/像素比率。有两种情况。如果缩放确实如此,那么数据/像素比率

如果比率 >1,我会加载适当数量的统计块(而不是数据块)并使用它们绘制图表。首先,我画了一个具有最小值和最大值的信封(两个系列之间有涂漆区域),然后我画了一个系列,即平均值 +/- 标准。偏差(sqrt(方差)。这样我可以显示这个块中的数据概览。因为我只读取统计块读取性能非常好(快)。如果文件足够大,统计块计数/像素比率变得更大超过 1 我可以简单地抽取统计数据块并进行绘图。

关于要加载的块数等...我必须进行一些试验,看看什么能给我最好的结果,但第一次试验确实令人鼓舞。稍后我将添加一些关于最终结果的 cmets 和一张照片来展示它。感谢您的想法和贡献。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-19
    • 2014-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-20
    • 1970-01-01
    相关资源
    最近更新 更多