我有一个复杂的结构化二进制文件。我在python中创建了一个解析器,用于读取二进制文件并转换为正确的值,并将数据保存到csv中,以便对值进行分析。这很好,但是有些文件非常大(即20+ Gb),需要很多时间来解析。我试图通过在c++中实现相同的过程来加快速度。
下面是一个摘录,它在每个逻辑记录的开头读取一个控制字,并指定记录的大小。对于特定情况,控制字为128 (4字节,Big,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值是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++编程以来,已经有很多年了。有什么事情我忘了做,以正确地映射我的二进制到我的结构??
我读过很多关于读取二进制文件的问题,不知道为什么我会得到这些奇怪的值。我找到的最接近的答案是就在这里,解决方案是用户没有将二进制数据块映射到正确的类型。我知道,在我的python实现中,b/c不是这样的,我将这个块作为一个int来读取,并得到我所期望的值。
发布于 2018-05-22 16:52:22
根据文档 > for,numpy.dtype指定大端格式.您正在运行您的代码,很可能是在英特尔或兼容的CPU,这是小终端。您需要使用uint32_t函数转换您的ntohl()字段:
in_f.read(reinterpret_cast<char*>(&cw), sizeof(cw));
cw.chunk_size = ntohl( cw.chunk_size );
cout << cw.chunk_size << endl;Endianness的详细信息
https://stackoverflow.com/questions/50472710
复制相似问题