将QByteArray转换为QDataStream并保存时出现的一些问题.请帮帮我



以下是我的代码:

QFile f("tql.dll"); //a file to be copied
f.open(QFile::ReadOnly);
QByteArray qba = f.readAll();
f.close();
QString hexstr = qba.toHex();
qba = QByteArray::fromHex(hexstr.toLatin1()); //i try this and it dose not change the original data
QFile f2("tql3.dll");
f2.open(QIODevice::ReadWrite);
QDataStream out(&f2);
out << qba;
f2.close();
qDebug() << "done" << "n"; //when i md5sum the tql3.dll.it is not the same as tql.dll

我用vim查看了tql.dll和tql3.dll的十六进制,找出了区别。然后我发现tql3.dll的顶部有"00 00 EC 00"多余的部分。为什么?

PS:我知道将QByteArray保存到QFile目录是可以的。但我只想尝试QDataStream。

QDatastream用于传输Qt类型,而不是纯二进制数据。

当您输出到QDataStream时,每个变量都有一个带有内部数据的头(我假设类型+长度)。

参见http://qt-project.org/doc/qt-4.8/QDataStream.html#details:

写入流中的每个项目都以预定义的二进制形式写入根据商品类型而变化的格式

数据流格式页面说明QByteArray的存储方式:

如果字节数组为空:0xFFFFFFFF(quint32)
否则:数组大小(quint32)后跟数组字节,即大小字节

因此,您发布的这四个字节(32位)就是字节数组的长度。

QDataStream应该用于序列化,因此我无法创建1:1的文件副本。

。实际上…有一种方法可以做到这一点。但首先你必须意识到你的代码有潜在的问题:

  1. 如果您试图使用十六进制字符串转换为二进制数据根本不起作用!记住,字符串实际上并不是表示二进制数据。例如:写入16位二进制"FF"以二进制(使用十六进制表示法)表示为FF。但是STRING FF是写的(使用相同的16位二进制格式)与46 46
  2. 使用QString::toLatin1()将NOT以unicode输出文本形式。我知道这可能不是你在这里的目标,但对将军来说为了知识起见,字符将只转换为Latin1格式如果它们是字符的ASCII等价物。如果你想要满unicode支持您应该使用QString::toUtf8()

现在是解决方案如果要将QByteArray转换为QDataStream,可以将QDataStream::writeBytes(const char*s,uint length)函数与QByteArray::data()和QByteArray::size()结合使用。

在您的代码中,您希望用以下内容替换out << qba行:

out.writeBytes(qba.data(), qba.size());

更安全的方法是使用以下代码:

for (int i = 0; i < qba.size(); ++i)
{
    out << (quint8)qba.at(i);
}

最新更新