读写QByteArray到QDataSteam

时间:2014-11-30 11:02:43

标签: c++ qt qbytearray qdatastream

我在通过QByteArray发送QDataStream时遇到了问题。 我创建了一个用于存储序列化消息的类,通过socket发送它,类看起来像这样:

#ifndef SERIALIZEDMESSAGE_H
#define SERIALIZEDMESSAGE_H
#include <QByteArray>
#include <QDataStream>
#include <QDebug>
class SerializedMessage
{
public:
  SerializedMessage();
  SerializedMessage(int type, QByteArray data);
  friend QDataStream &operator<<(QDataStream &out, const SerializedMessage &message);
  friend QDataStream &operator >>(QDataStream &in, SerializedMessage &message);
  QByteArray dataArray() const;
  void setDataArray(const QByteArray &dataArray);

private:
  int m_type;
  QByteArray m_dataArray;
};
SerializedMessage::SerializedMessage()
{
}

SerializedMessage::SerializedMessage(int type, QByteArray data)
  :m_type(type), m_dataArray(data)
{

}
QByteArray SerializedMessage::dataArray() const
{
  return m_dataArray;
}

void SerializedMessage::setDataArray(const QByteArray &dataArray)
{
  m_dataArray = dataArray;
}


QDataStream &operator<<(QDataStream &out, const SerializedMessage &message)
{
  out << qint32(message.m_type);
  qDebug() << "write type" << message.m_type;
  out << qint32(message.m_dataArray.length());
  qDebug() << "write data lenght" << message.m_dataArray.length();
  int bytesWritten = out.writeRawData(message.m_dataArray.data(), message.m_dataArray.length());
  qDebug() << bytesWritten << "bytes written";
  qDebug() << "write data base64" << message.m_dataArray.toBase64();
  return out;
}

QDataStream &operator >>(QDataStream &in, SerializedMessage &message)
{
  qint32 type;
  qint32 dataLength;
  QByteArray dataArray;
  char * tmp;
  in >> type >> dataLength;
  qDebug() << "read type" << type;
  qDebug() << "read data lenght" << dataLength;
  int bytesRead = in.readRawData(dataArray.data(), dataLength);
  qDebug() << bytesRead << "bytes read";
  qDebug() << "read data length" << dataArray.length();
  qDebug() << "read data base64" << dataArray.toBase64();
  message = SerializedMessage(type, dataArray);
  return in;
}

要测试运营商QDataStream & operator>>QDataStream &operator<<,我已创建了testunit。

#include <QString>
#include <QtTest>
#include <QDebug>
#include "textmessage.h"
#include "serializedmessage.h"
class Serialization_test : public QObject
{
  Q_OBJECT

public:
  Serialization_test();

private Q_SLOTS:
  void textMessageSerialization();
  void serializedMessageFromArray();
};

Serialization_test::Serialization_test()
{
}

void Serialization_test::textMessageSerialization()
{
  TextMessage txtMessage(QString("sender"), QString("message"));
  SerializedMessage serialized = txtMessage.toSerializedMessage();
  TextMessage deserialized = TextMessage::fromSerializedMessage(serialized);
  QCOMPARE(txtMessage.sender(), deserialized.sender());
  QCOMPARE(txtMessage.message(), deserialized.message());
}

void Serialization_test::serializedMessageFromArray()
{
  TextMessage txtMessage(QString("sender"), QString("message"));
  SerializedMessage serialized = txtMessage.toSerializedMessage();
  SerializedMessage outSerialized;

  QByteArray sr;
  QDataStream inputStream(&sr, QIODevice::WriteOnly);
  inputStream << serialized;

  QDataStream outputStream(sr);
  outputStream >> outSerialized;

  TextMessage outText = TextMessage::fromSerializedMessage(outSerialized);
  QCOMPARE(txtMessage.sender(), outText.sender());
  QCOMPARE(outText.message(), outText.message());
}

QTEST_APPLESS_MAIN(Serialization_test)

#include "tst_serialization_test.moc"

要正确运行此测试,您需要TextMessage

#ifndef TEXTMESSAGE_H
#define TEXTMESSAGE_H
#include <QString>
#include <QDataStream>
#include "serializedmessage.h"

class TextMessage
{
public:
  TextMessage(const QString & sender, const QString & message);
  SerializedMessage toSerializedMessage();
  static TextMessage fromSerializedMessage(const SerializedMessage &msg);
  QString sender() const;
  void setSender(const QString &sender);

  QString message() const;
  void setMessage(const QString &message);

private:
  QString m_sender;
  QString m_message;
};

#include "textmessage.h"

TextMessage::TextMessage(const QString &sender, const QString &message)
  : m_sender(sender), m_message(message)
{
}

TextMessage TextMessage::fromSerializedMessage(const SerializedMessage & msg)
{
  QString sender;
  QString message;
  QDataStream stream(msg.dataArray());
  stream >> sender >> message;
  TextMessage textMessge(sender, message);
  return textMessge;
}
QString TextMessage::sender() const
{
  return m_sender;
}

void TextMessage::setSender(const QString &sender)
{
  m_sender = sender;
}
QString TextMessage::message() const
{
  return m_message;
}

void TextMessage::setMessage(const QString &message)
{
  m_message = message;
}




SerializedMessage TextMessage::toSerializedMessage()
{
  QByteArray data;
  QDataStream stream(&data, QIODevice::WriteOnly);
  stream << m_sender << m_message;
  SerializedMessage message(1, data);
  return message;
}

#endif // TEXTMESSAGE_H

我的问题是当我运行void Serialization_test::serializedMessageFromArray()时,测试挂断或失败并显示消息

FAIL!  : Serialization_test::serializedMessageFromArray() Compared values are not the same
   Actual   (txtMessage.sender()): "sender"
   Expected (outText.sender())   : ""

更重要的是,调试读写操作符显示out.writeRawData(message.m_dataArray.data(), message.m_dataArray.length());写入相同的数据,在in.readRawData(dataArray.data(), dataLength);中读取。我不太确定发生了什么。我将不胜感激任何帮助

1 个答案:

答案 0 :(得分:1)

您的问题出在operator >>(QDataStream&, SerializedMessage&)。在尝试使用QByteArray将字节写入其中之前,必须确保QDataStream::readRawData的大小正确:

QDataStream &operator >>(QDataStream &in, SerializedMessage &message)
{
  qint32 type;
  qint32 dataLength;
  QByteArray dataArray;
  in >> type >> dataLength;
  dataArray.resize(dataLength);  // <-- You need to add this line.
  int bytesRead = in.readRawData(dataArray.data(), dataLength);
  // Rest of function goes here.
}