我有一个复杂的结构化二进制文件。我在python中创建了一个解析器来读取二进制文件并转换为正确的值并将数据保存到csv,以便可以分析这些值。这很好用,但有些文件非常大(即20+ Gb),需要花费很多时间才能解析。我试图通过在c ++中实现相同的过程来加快速度。
下面是一段摘录,它读取每个逻辑记录开头的控制字并指定记录的大小。对于特定情况,控制字是128(4字节,Big Endian,int)。在python我做:
x = open(str(self.filename), "rb")
cw_d_type = np.dtype('>i4')
temp = np.frombuffer(x.read(cw_d_type.itemsize), dtype=cw_d_type)
此后temp [0]中的值为128.现在,当我尝试使用以下代码在c ++中执行相同的操作时
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <sstream>
#include <stdint.h>
using namespace std
struct control_word
{
uint32_t chunk_size;
}
int main()
{
// define my stream
ifstream in_f("Y:/path_to_binary_file/binary_file", ios::binary | ios::in | ios::ate);
// find the size of the file
int file_size = in_f.tellg();
// goto the beginning of the file
in_f.seekg(0, std::ios::beg);
in_f.read(reinterpret_cast<char*>(&cw), sizeof(cw));
cout << cw.chunk_size << endl
... continue reading the rest of the structures
}
cw.chunk_size = 2147483648的结果。我知道我正在读取文件b / c中的正确位置我读到的下一个结构有一个32位字符串并且正在正确读取,如果我不在在文件中的正确位置,那么结果将是不正确的。
如果我将控制字结构从int
更改为char[4]
,则结果为[0][0][0][-128]
,除了负号外,几乎正确。
我读到的所有双打和花车都表现出同样的东西。似乎唯一正确阅读的是char
值。自从我上次用c ++编程以来已经有好几年了。有什么东西我忘记做正确地将我的二进制映射到我的结构?
我读过许多关于阅读二进制文件的问题,但无法弄清楚为什么我会得到这些奇怪的值。我找到的最接近的答案is here,解决方案是用户没有将二进制块映射到正确的类型。我知道在我的python实现中我不是这样的b / c我将块读作int
并获得我期望的值。
答案 0 :(得分:2)
根据documentation&gt; for numpy.dtype指定Big-Endian格式。您最有可能在Intel或兼容的Little-Endian上运行代码。您需要使用uint32_t
函数转换ntohl()
字段:
in_f.read(reinterpret_cast<char*>(&cw), sizeof(cw));
cw.chunk_size = ntohl( cw.chunk_size );
cout << cw.chunk_size << endl;
的详细信息