Delphi到Qt/C++:t内存流

Delphi to Qt/C++ : tmemorystream

本文关键字:内存 C++ Qt Delphi      更新时间:2023-10-16

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

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

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

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

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

在Qt中,我必须读取文件:

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

如何像在Delphi代码中一样将前2个字节读入h1?Delphi似乎有一种方法可以指定从流/字节数组中读取的字节数为整数表示,但这似乎是相反的。

我能在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代码(变量h1)中那样,将一系列字节提取成一个长/整数?

实际上他们都错了。问题是字节序之一。读取整数时,应注意文件的字节序。

在十六进制编辑器中打开文件,查看遇到问题的整数。如果最低有效字节是第一个,则它是小端序。如果最高有效字节位于第一位,则为big-endian。(是的,这都是参考《格列佛游记》。)

当你的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();

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

希望这能有所帮助。

Duthomas在endian问题上是正确的。您必须知道文件的格式才能正确读取。

要回答问题的另一部分,您需要使用Qt的QIOStream类,以便在更精细的级别访问文件。您还可以告诉QUIStream文件的endian格式,它会为您修复数字。