从大型二进制文件读取数据的任何有效方法?

时间:2009-08-17 12:40:42

标签: python file binary

我需要在一个二进制文件中处理数十GB的数据。数据文件中的每条记录都是可变长度。

所以文件就像:

<len1><data1><len2><data2>..........<lenN><dataN>

数据包含整数,指针,双精度值等。

我发现python甚至无法处理这种情况。如果我在内存中读取整个文件没有问题。它很快。但似乎struct包不擅长性能。它几乎坚持解压缩字节。

感谢任何帮助。

感谢。

6 个答案:

答案 0 :(得分:5)

其他答案推荐的

structarray对于实现的细节很好,如果您的需求总是按顺序读取所有文件或前缀,则可能只需要它们它的。其他选项包括buffermmap,甚至ctypes,具体取决于您未提及的有关您的确切需求的许多详细信息。如果没有合适且可访问的库(在C,C ++,Fortran等中)已经存在,可以为了处理这个庞大的文件而进行接口,那么也许一个专门的Cython编码助手可以提供您所需的所有额外性能。你需要。

但显然这里存在一些特殊问题 - 例如,数据文件如何包含指针,这本质上是一个与寻址内存相关的概念?它们可能是“抵消”,如果是这样,它们究竟是如何基于和编码的?您的需求是否比简单的顺序读取(例如,随机访问)更先进,如果是这样,您是否可以进行第一次“索引”传递以将所有从文件开始到记录开始的偏移变为更可用,更紧凑的,手工格式化的辅助文件? ( 偏移量的二进制文件对于array来说是很自然的 - 除非偏移量需要比机器上的array支持更长!)。记录长度和组成的分布以及构成“数十千兆字节”的记录数量是多少?等等。

你有一个非常大规模的问题(毫无疑问是非常大规模的硬件支持它,因为你提到你可以轻松地将所有文件读入内存,这意味着一个64位的盒子有几十GB的RAM - 哇!),所以非常值得细致处理以优化其处理 - 但除非我们知道足够的细节,否则我们对这种详细的护理无能为力! - 。)。

答案 1 :(得分:2)

查看array模块,特别是array.fromfile方法。这一点:

  

数据文件中的每条记录都是可变长度。

非常不幸。但你可以使用try-except子句处理它。

答案 2 :(得分:2)

对于类似的任务,我定义了一个这样的类:

class foo(Structure):
        _fields_ = [("myint", c_uint32)]

创建了一个实例

bar = foo()

并且做了,

block = file.read(sizeof(bar))
memmove(addressof(bar), block, sizeof(bar))

如果是可变大小的记录,您可以使用类似的方法来检索 lenN ,然后读取相应的数据条目。实现起来似乎微不足道。但是,我不知道这个方法与使用 pack() unpack()相比有多快,也许其他人已经描述了这两种方法。

答案 3 :(得分:2)

有关解析文件而不将其读入内存的帮助,您可以使用bitstring模块。

在内部,这是使用struct模块和bytearray,但是不可变的Bits对象可以用文件名初始化,因此它不会将它全部读入内存。

例如:

from bitstring import Bits

s = Bits(filename='your_file')
while s.bytepos != s.length:
    # Read a byte and interpret as an unsigned integer
    length = s.read('uint:8')
    # Read 'length' bytes and convert to a Python string
    data = s.read(length*8).bytes
    # Now do whatever you want with the data

当然,您可以根据需要解析数据。

您也可以使用切片表示法来读取文件内容,但请注意索引将以位而不是字节为例,因此例如s[-800:]将是最后的100个字节。

答案 4 :(得分:1)

如果您将数据文件转储到内存中的sqlite3,该怎么办?

import sqlite3
sqlite3.Connection(":memory:")

然后,您可以使用sql处理数据。

此外,您可能希望查看generators(或here)和iterators(或herehere)。

答案 5 :(得分:1)

PyTables是一个非常好的库来处理HDF5,这是一种用于天文学和气象学的二进制格式,用于处理非常大的数据集:

它或多或少类似于分层数据库,您可以在列中存储多个表。看看吧。