使用 Qdatastream 从套接字读取数据并写入文件

Che*_* Xu 6 sockets qt file qdatastream

我需要通过 QTcpSocket 接收二进制数据(读取浮点数)并使用 QDatastream 将它们写入 Qfile。但是我在使用 QDataStream 时遇到了一些问题。如下,我只能用这种方式来实现吗?

QDataStream in(socket);
in.setFloatingPointPrecision ( QDataStream::SinglePrecision);
float data;
in >> data;

QFile file("file.dat"); 
file.open(QIODevice::WriteOnly); 
QDataStream out(&file);
out << data;
Run Code Online (Sandbox Code Playgroud)

我必须创建两个 Qdatastream 并在读取它后将浮点数写入 Qfile。我的意思是,我可以读取流并将其直接通过一个 Qdatastream 写入文件以提高效率。

我对 QDataStream 的使用有一些盲点吗?有人可以帮我解决我的问题吗?非常感谢。

Ore*_*era 2

QDataStream旨在提供独立于平台的数据序列化。

例如,您想要以某种二进制格式将一些浮点数保存到文件中(或通过 tcp 流发送)。然后这个浮点数应该从另一台具有不同 CPU 甚至不同字节顺序(字节顺序)的 PC 上的文件中读取(或从 tcp 接收)。

因此,QDataStream可以用于此类任务。它允许您对 C++ 基本数据类型进行编码并在任何其他平台上解码原始值。

如果您只想将 TCP 流中的二进制数据按原样保存到二进制文件,那么您不需要QDataStream. 您可以直接同步阻塞线程或使用readyRead()套接字信号异步执行此操作。

示例 1. 阻塞非 GUI 线程的套接字

QFile file("out.bin");
if (!file.open(QIODevice::WriteOnly))
    return;

char buffer[50];
forever {
    int numRead  = socket.read(buffer, 50);
    // do whatever with array
    file.write(buffer, numRead);

    if (numRead == 0 && !socket.waitForReadyRead())
        break;
}
Run Code Online (Sandbox Code Playgroud)

示例 2. 异步非阻塞套接字

// This slot is connected to QAbstractSocket::readyRead()
void SocketClass::readyReadSlot()
{
    while (!socket.atEnd()) {
        QByteArray data = socket.read(100);
        file.write(data);
    }
}
Run Code Online (Sandbox Code Playgroud)

这些示例基于QAbstractSocket 类的文档(您可以在那里找到其工作原理的详细说明)。