Delphi到Qt / C ++:tmemorystream

时间:2015-11-08 19:49:50

标签: c++ qt delphi

我有一些需要转换为Qt / C ++的Delphi代码。

整体代码读取二进制数据文件,并提取部分数据。

Delphi代码按如下方式读取文件内容:

var
   m1 tmemorystream;
   h1 integer;
.
.
m1 := tmemorystream.Create;
m1.LoadFromFile(paramstr[1]);
m1.Read (h1, 2);

现在,如果文件中的前2个字节是" 01 00",我希望h1为0x0100,但它似乎在读它" Backwards"所以h1中的值实际上是" 00 01",即0x1。

Qt中的等价物我必须阅读文件:

QFile fileIn(iFile);
if (!fileIn.open(QIODevice::ReadOnly)) return;
QByteArray m1 = fileIn.readAll();

如何将前2个字节读入h1,与Delphi代码相同? Delphi似乎有办法指定从流/ bytearray读取的整数表示的字节数,但这似乎是相反的。

我在Qt中可以想到达到相同结果的等价物是:

 QString tStg;
 tStg.sprintf ( "0x%02x%02x", getUChar ( m1, 1), getUChar ( m1, 0) );
 bool ok;
 unsigned long h1;
 h1 = tStg.toLong(&ok,16);

看起来啰嗦而且不优雅...我认为我是C ++的新手。

所以我的问题首先是在Qt中直接相当于Delphi的tmemeorystream.Read吗?

有没有更好的方法将字节范围提取到像Delphi代码(变量h1)中的sinlge long / integer一样?

2 个答案:

答案 0 :(得分:2)

实际上,他们都错了。问题是 endianness 之一。读取整数时,您应该知道文件的字节序。

在十六进制编辑器中打开文件,看看你遇到问题的整数。如果最低有效字节是第一个,则它是 little-endian 。如果最重要的字节是第一个,则它是 big-endian 。 (是的,这都是 Gulliver's Travels 的参考。)

当您的C ++代码读取文件时,请务必知道如何修复它。在我看来,最好的方法是始终按字节读取并将值移位到适当的位置:

// little endian
int x = 0;
x  = (unsigned char)f.get();
x |= (unsigned char)f.get() << 8;
x |= (unsigned char)f.get() << 16;
x |= (unsigned char)f.get() << 24;

// big endian
int x = 0;
x            = (unsigned char)f.get();
x <<= 8;  x |= (unsigned char)f.get();
x <<= 8;  x |= (unsigned char)f.get();
x <<= 8;  x |= (unsigned char)f.get();

当然,您可以通过将大块文件读入数组并从数组中解码而不是逐字节文件读取来加快速度。

希望这有帮助。

答案 1 :(得分:2)

Duthomas关于端序问题是正确的。您必须知道文件的格式才能正确阅读。

要回答问题的其他部分,您需要使用Qt的QIOStream类才能更精细地访问该文件。您还可以告诉QUIStream文件具有哪种字节序格式,它将为您修复数字。