如何正确地以XML存储原始字节数据并进行恢复?

时间:2020-01-07 13:11:54

标签: c++ qt

使用C ++和Qt,我需要在QDomElement(XML节点)中存储一些原始字节数据(无符号char数组),然后再进行恢复,以便可以将其与直接写入的原始数据进行比较。一个不同的二进制文件。在测试期间,我注意到我的解决方案在大约85%的时间内都能正常工作,但是比较恢复的数据和从文件读取的原始数据似乎有时会失败。下面的代码段说明了我当前使用的Qt方法。我对不同的字符编码以及这方面需要注意的知识知之甚少,所以我假设我的错误与这有关。

以XML存储原始数据:

QDomElement myElement;
unsigned char rawData[ DATA_LEN ];
foo( rawData );  // upon return, rawData now contains the data I want to store in XML
QByteArray dataByteArray( reinterpret_cast< char * >( rawData ) );
QString dataStr( dataByteArray.toBase64() );
QByteArray excluded = " /():|+,.=[]_^{}";
myElement.setAttribute( "Data", QUrl::toPercentEncoding( dataStr, excluded ) );

从XML恢复数据并与从二进制文件读取的原始数据进行比较(memcmp()有时会失败):

unsigned char recoveredData[ DATA_LEN ];
QString dataStr = QUrl::fromPercentEncoding( stringFromXmlNode.toUtf8() );
QByteArray dataByteArray = QByteArray::fromBase64( dataStr.toAscii() );
memcpy( recoveredData, reinterpret_cast< unsigned char * >( dataByteArray.data() ), DATA_LEN );

unsigned char dataFromFile[ DATA_LEN ];
fread( dataFromFile, 1, DATA_LEN, filePtr );
if( 0 != memcmp( dataFromFile, recoveredData, DATA_LEN ) )
{
    return false;
}

我只能使用Qt 4.8,因此请尽量避免使用任何Qt5专用解决方案,谢谢!

3 个答案:

答案 0 :(得分:1)

您声明字节是随机的,因此它们可以包含0个字节。字节值0是C样式字符串中的字符串终止符。您代码中的这一行从这样的字符串初始化QByteArray dataByteArray( reinterpret_cast< char * >( rawData ) );

rawData

解决方案还需要传递startActivityForResult(new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS).setData(Uri.parse("package:"+getPackageName()) ),0); 的长度并使用this constructor

答案 1 :(得分:0)

您要使用XML CDATA部分。

QDomCDATASection

https://doc.qt.io/archives/qt-4.8/qdomcdatasection.html

答案 2 :(得分:0)

为什么不使用QDataStream来定义字节顺序(如果在不同平台上交换数据则很重要)和版本控制?

从Qt 4.8文档页面:

数据流与QIODevice紧密协作。 QIODevice表示一种输入/输出介质,可以从中读取数据或向其写入数据。 QFile类是I / O设备的示例。

示例(将二进制数据写入流):

QFile file("file.dat"); 
file.open(QIODevice::WriteOnly); 
QDataStream out(&file);   // we will serialize the data into the file
out << QString("the answer is");   // serialize a string 
out << (qint32)42;  // serialize an integer

示例(从流中读取二进制数据):

QFile file("file.dat"); 
file.open(QIODevice::ReadOnly); 
QDataStream in(&file);    // read the data serialized from the file 
QString str;
qint32 a;
in >> str >> a;  // extract "the answer is" and 42

写入流的每个项目均以预定义的二进制文件写入 格式因项目类型而异。支持的Qt类型 包括QBrush,QColor,QDateTime,QFont,QPixmap,QString,QVariant 还有很多其他有关所有Qt类型支持数据的完整列表 观看Serializing Qt Data Types

您可以使用QDataStream读取/写入XML数据,然后使用QDomDocument函数setContent()toByteArray()将它们导入QDomDocument结构中。