2010-07-02 56 views
1

我需要存储一个由4个字段组成的12字节头的二进制文件。它们是:sSamples(4字节整数),sSampPeriod(4字节整数),sSampSize(2字节整数),最后是sParmKind(2字节整数)。 我使用'结构'我的变量到所需的字段。现在我已经分别定义了它们,我怎样才能将它们全部合并来存储'12字节头'?将“结构”数据存储到二进制文件

sSamples  = struct.pack('i', nSamples) # 4-bytes integer 
sSampPeriod  = struct.pack('i', nSampPeriod) # 4-bytes integer 
sSampSize  = struct.pack('H', nSampSize) # 2-bytes integer/unsigned short 
sParmKind  = struct.pack('H', 9) # 2-bytes integer/unsigned short 

此外,我已经维数d(numpy.ndarray - FLOAT32)的npVect float数组。我怎样才能将这个矢量存储在同一个二进制文件中,但在标题之后?

+3

请注意,您可以一次打包多个值:struct.pack('Hi',foo,bar)。另外,你应该在格式化字符串之前加上一个'>'或'<',这样它就可以在不同字节顺序的系统上正确打包和解压缩。 – 2010-07-02 10:58:33

回答

1

struct.pack返回一个字符串,那么你可以简单地通过字符串连接相结合的领域:

header = sSamples + sSampPeriod + sSampSize + sParmKind 
assert len(header) == 12 
+0

嗨jhcl,谢谢你的建议!要将头文件存储到二进制文件,这是。如: binfile = open('myfile.dat','wb') binfile.write(header) 然后,我怎样才能将'npVect'变量附加到'binfile'? – Javier 2010-07-02 10:59:31

+0

这对于将值写入文件来说是完全正确的。我对numpy不熟悉,所以我会让别人评论一下。 – jchl 2010-07-02 11:25:43

2

由于科迪·布罗克斯写道,你可以一次打包整个头:

header = struct.pack('<iiHH', nSamples, nSampPeriod, nSampSize, nParmKind) 

他还如果您想要打包数据以便可靠地将其解包到具有不同架构的机器上,这一点非常重要。格式字符串开头的<指定“使用小端规则打包此数据”。

至于数组,你必须打包它的长度,以便确定在再次读取时解压缩多少个值。做这一切在一个电话:

flattened = npVect.ravel() # get a 1-D array of numbers 
arrSize = len(flattened) 
# pack header, count of numbers, and numbers, all in one call 
packed = struct.pack('<iiHHi%df' % arrSize, 
    nSamples, nSampPeriod, nSampSize, nParmKind, arrSize, *flattened) 

根据您的阵列有多大可能是,你可以结束了一个巨大的字符串表示的二进制文件的全部内容,你可能想寻找到替代品到struct这不需要你在内存中拥有整个文件。

开箱:

fmt = '<iiHHi' 
nSamples, nSampPeriod, nSampSize, nParmKind, arrSize = struct.unpack(fmt, packed) 
# Use unpack_from to start reading after the packed header and count 
flattened = struct.unpack_from('<%df' % arrSize, packed, struct.calcsize(fmt)) 
npVect = np.ndarray(flattened, dtype='float32').reshape(# your dimensions go here 
    ) 

编辑:哎呀,阵列格式不太一样简单:)总体思路认为,虽然:压扁你的数组使用任何方法号码列表你喜欢,打包数值,然后打包每个值。另一方面,将数组作为平面列表读取,然后在其上施加任何需要的结构。

编辑:更改格式字符串以使用重复说明符而不是字符串乘法。感谢John Machin指出。

编辑:增加了numpy代码,在打包之前对数组进行扁平化并在拆包之后进行重构。

+2

'' 2010-07-02 11:46:34

+0

+1好点,忘记了你可以把数字放在那里。如果数组*虽然真的很大,但仍然会将许多参数传递给'pack',这要归功于元组解开数组,并且您将从中返回一个巨大的字符串。如果性能受到影响,这两者都指向寻找“struct”的替代品。 – shambulator 2010-07-02 11:55:13

+0

嗨,大家好,我遵循以下建议:arrSize = len(arr) packed = struct.pack(' Javier 2010-07-02 13:43:52

相关问题