【问题标题】:Size of QByteArray is hard to compute?QByteArray 的大小很难计算?
【发布时间】:2013-12-01 13:20:42
【问题描述】:

最近我编写了用 Qt 进行文件传输的程序。认为它现在有效,我仍然对发生的事情感到好奇。请帮我找出原因。非常感谢。

为什么head的大小大于sizeof(qin32)、sizeof(qint32)和文件名长度之和?(我猜是函数-setVersion()的原因)

QFileInfo info(file_to_send.fileName());
QByteArray head;
QDataStream out(&head, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_5_0);
out << qint32(file_to_send.size() + info.fileName().length() + sizeof(qint32)*2)
    << qint32(info.fileName().length())
    << info.fileName();
tcpClient.write(head);

【问题讨论】:

  • 客户端头部尺寸:40 |客户端标题:[252592][14][“Screenshot.png”]

标签: qt qbytearray


【解决方案1】:

info.filename()writes out its own length

如果你不想这样做,那么你可以这样做

QFileInfo info(file_to_send.fileName());
QByteArray head;
QDataStream out(&head, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_5_0);
QByteArray filename = info.fileName().toLatin1();
out << qint32(file_to_send.size() + filename .length() + sizeof(qint32)*2);
    << qint32(filename .length())
out.writeRawData(fileName.constData(), filename.length());
tcpClient.write(head);

使用writeRawData 绕过任何内置编码

【讨论】:

  • 太好了,很有帮助!我必须在客户端和服务器中使用相同的类吗?我在客户端使用了 QString,发现在服务器中使用 QByteArray(在 >> QByteArray 中)不起作用。
  • 是的,你是对的! 4 + 4 + 4(QString 长度) + 2*(QString, UTF-16) = 4 + 4 + 4 + 2*strlen("Screenshot.png") = 40(标题大小)
【解决方案2】:

你把事情弄得很复杂。模式是这样的:

QFileInfo info(file_to_send.fileName());
QByteArray head;
QDataStream out(&head, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_5_0);
out << qint32(0)
    << info.fileName(); // << YouCanAddMoreStuffHere;

out.device()->seek(0);
out << qint32(out.length());

tcpClient.write(head);

并阅读代码:

void SomeClass::slotReadClient() { // slot connected to readyRead signal of QTcpSocket
    QTcpSocket *tcpSocket = (QTcpSocket*)sender();
    QDataStream clientReadStream(tcpSocket);

    while(true) {
        if (!next_block_size) {
            if (tcpSocket->bytesAvailable() < sizeof(qint32)) { // are size data available
                break;
            }
            clientReadStream >> next_block_size;
        }

        if (tcpSocket->bytesAvailable() < next_block_size) {
            break;
        }
        QString fileName;
        clientReadStream >> fileName; // >> YouCanAddMoreStuffHere; // same as above

        next_block_size = 0;
    }
}

【讨论】:

  • 好吧,你漏掉了完整尺寸,它是用来更新我在服务器中的进度条的。你介意帮我解决我的困惑吗?
  • QData 流正在存储字符串的大小,因此您不必也编写它。在此模式中,仅需要乞求大小来验证完整内容是否已经可用,因为如果不是所有流数据都可用,QDataStreamQTcpSocket 将无法正常工作(套接字以块的形式传递数据,而不必反映发送过程)。无论如何QDataStream 存储项目的大小,如果有必要的话。
  • 哦,我才明白你的意思。谢谢!
猜你喜欢
  • 2018-02-25
  • 2023-03-04
  • 2014-06-15
  • 2011-03-02
  • 2016-05-03
  • 2011-04-09
  • 2019-05-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多