QTcpSocket::write - 如何写入大文件?

Posted

技术标签:

【中文标题】QTcpSocket::write - 如何写入大文件?【英文标题】:QTcpSocket::write - how to write large files? 【发布时间】:2016-07-19 16:42:36 【问题描述】:

QIODevice::Write 的 qt 文档说:

qint64 QIODevice::write(const char *data, qint64 maxSize)

从数据到设备最多写入 maxSize 个字节的数据。返回实际写入的字节数,如果发生错误,则返回 -1。

但是我在网上找到的每个代码示例似乎都使用如下:

QByteArray block;
... fill the block...
socket->write(block);

或如下

QByteArray block;
... fill the block...
auto written_bytes = socket->write(block);
if(written_bytes < block.size())
   throw error()..

假设我有一个大文件(比如 2 GB)要发送,我应该使用第一种方法还是后一种方法?我怀疑 2GB 只能通过 TCP 发送一个块,对吧?

还是我应该使用类似下面的东西?

QByteArray block;
... fill the block with 2GB of data...
auto written_bytes = 0;
while(written_bytes < 2GB) 
    // Restart each time where we previously left
    written_bytes += socket->write(block + written_bytes, 2GB - written_bytes);

我很困惑

【问题讨论】:

实际 TCP/IP 数据包大小(以太网上的 MTU)约为 1500 字节,因此您的数据将被分块。写出对您来说最明显且易于维护的内容。 哦,如果write 无法写入这 5-6 个字节,那么假设一个 5-6 字节的小“ping”是否绝对安全/合理? 除非您使用非阻塞套接字,否则读取/写入将阻塞。 我认为在QByteArray 中有 2GB 的数据也是一个坏主意,您需要分块读取和发送数据。 . . @RichardCritten 这是 Qt。套接字默认是异步的。 【参考方案1】:

您需要以合理大小的块继续读取文件,并将这些块提供给套接字。您可以动态调整块大小以保持套接字流的开销很小,即对低传输缓冲区水印做出反应的代码不应该每秒激活超过十几次左右。对于非常大的文件,如您的情况,目标是每秒重新填充一次。

示例代码见this answer。

【讨论】:

以上是关于QTcpSocket::write - 如何写入大文件?的主要内容,如果未能解决你的问题,请参考以下文章

Python QtNetwork.QTcpSocket.readAll() 和 QtNetwork.QTcpSocket.write() 不起作用

QTcpSocket write 发不出去

无法使用 QtNetwork,因为应用程序使用不同的线程

在内存有限的系统上写入大文件时如何避免 mapFailed() 错误

如何以块的形式写入文件以规避大文件大小的错误?

如何使用实验性 API 将大文件写入 Blobstore?