如何从文件中读取结构化二进制数据?
How to read structured binary data from a file?
以下 C++ 代码将 header 写入文件:
#include <iostream>
struct Header
{
uint16_t name;
uint8_t type;
uint8_t padding;
uint32_t width, height;
uint32_t depth1, depth2;
float dMin, dMax;
};
int main()
{
Header header;
header.name = *reinterpret_cast<const uint16_t*>("XO");
header.type = true;
header.width = (uint32_t)512;
header.height = (uint32_t)600;
header.depth1 = (uint32_t)16;
header.depth2 = (uint32_t)25;
header.dMin = 5.0;
header.dMax = 8.6;
FILE* f = fopen("header.bin", "wb");
fwrite(&header, sizeof(Header), 1, f);
}
我希望使用 Python 阅读这些 header.bin
文件。在 C++ 中,我会做类似的事情:
fread(&header, sizeof(Header), 1, f)
但我不确定如何读取字节并将它们转换为 Header 结构在 Python 中具有的相应字段?
我会用 Python 的 ctypes 做这个,这样你就可以分享 Header header
从 ctypes.Structure
创建一个 class 来映射类型
import ctypes
class StructHeader(ctypes.Structure):
_fields_ = [
("name", ctypes.c_uint16),
("type", ctypes.c_uint8),
...
]
并创建一个函数,它可以用像
这样的签名来做你想做的事
int header(struct Header &buffer)
{
// open the file and write to buffer
// opportunity for other features
}
然后你可以编译一个shared object来读取它returns那个类型
gcc -shared -Wl,-soname,your_soname \
-o library_name file_list library_list
并用 ctypes.CDLL
呼出阅读 headers
header = ctypes.CDLL("mylib.so.1").header # function named header
header.argtypes = [ctypes.POINTER(StructHeader)]
header.restype = ctypes.c_int
# allocate struct for write
buffer = StructHeader()
# call out to function to write buffer
header(buffer)
使用 struct
module 定义类 C 结构的二进制布局,de-/serialise 它:
import struct
# Format String describing the data layout
layout = "H B x 2L 2L 2f"
# Object representing the layout, including size
header = struct.Struct(layout)
with open("header.bin", "rb") as in_stream:
print(header.unpack(in_stream.read(header.size))
layout
是一个 format string 描述字段的顺序,例如H
表示 uint16_t
,B
表示 uint8_t
,x
表示填充字节,依此类推。
以下 C++ 代码将 header 写入文件:
#include <iostream>
struct Header
{
uint16_t name;
uint8_t type;
uint8_t padding;
uint32_t width, height;
uint32_t depth1, depth2;
float dMin, dMax;
};
int main()
{
Header header;
header.name = *reinterpret_cast<const uint16_t*>("XO");
header.type = true;
header.width = (uint32_t)512;
header.height = (uint32_t)600;
header.depth1 = (uint32_t)16;
header.depth2 = (uint32_t)25;
header.dMin = 5.0;
header.dMax = 8.6;
FILE* f = fopen("header.bin", "wb");
fwrite(&header, sizeof(Header), 1, f);
}
我希望使用 Python 阅读这些 header.bin
文件。在 C++ 中,我会做类似的事情:
fread(&header, sizeof(Header), 1, f)
但我不确定如何读取字节并将它们转换为 Header 结构在 Python 中具有的相应字段?
我会用 Python 的 ctypes 做这个,这样你就可以分享 Header header
从 ctypes.Structure
创建一个 class 来映射类型
import ctypes
class StructHeader(ctypes.Structure):
_fields_ = [
("name", ctypes.c_uint16),
("type", ctypes.c_uint8),
...
]
并创建一个函数,它可以用像
这样的签名来做你想做的事int header(struct Header &buffer)
{
// open the file and write to buffer
// opportunity for other features
}
然后你可以编译一个shared object来读取它returns那个类型
gcc -shared -Wl,-soname,your_soname \
-o library_name file_list library_list
并用 ctypes.CDLL
呼出阅读 headers
header = ctypes.CDLL("mylib.so.1").header # function named header
header.argtypes = [ctypes.POINTER(StructHeader)]
header.restype = ctypes.c_int
# allocate struct for write
buffer = StructHeader()
# call out to function to write buffer
header(buffer)
使用 struct
module 定义类 C 结构的二进制布局,de-/serialise 它:
import struct
# Format String describing the data layout
layout = "H B x 2L 2L 2f"
# Object representing the layout, including size
header = struct.Struct(layout)
with open("header.bin", "rb") as in_stream:
print(header.unpack(in_stream.read(header.size))
layout
是一个 format string 描述字段的顺序,例如H
表示 uint16_t
,B
表示 uint8_t
,x
表示填充字节,依此类推。