如何确定要读取的QIODevice的总大小?

时间:2023-02-06 10:13:18

I'm using qt 5.3.

我正在使用qt 5.3。

I have a big thing written into a QIODevice for read. I want to have a proxy to get the data while keep the data in QIODevice available for the other thing to read. So if I call readAll() I will get everything good in proxy but the other reader cannot get any data.

我有一个很大的东西写入QIODevice进行阅读。我希望有一个代理来获取数据,同时保持QIODevice中的数据可供其他东西读取。因此,如果我调用readAll(),我会在代理中获得一切好处,但其他读者无法获取任何数据。

I think I should use peek() but this seems requires a maxsize. I tried for passing size() or bytesAvailable() but they didn't get me the real size. They returns probably a buffer size of some weird value as 3287. But my data is as huge as 1081530 bytes.

我想我应该使用peek(),但这似乎需要一个maxsize。我尝试传递size()或bytesAvailable(),但他们没有让我真正的大小。它们可能返回一个奇怪值的缓冲区大小为3287.但我的数据与1081530字节一样大。

How can I get the true size of my QIODevice for read?

如何才能获得我的QIODevice的真实尺寸?

Edit: The QIODevice I mensioned above is actually QNetworkReply. I want to create a proxy to observe request and response data of my program with a QWebView to access some flash games. I implemented createRequest of my subclass of QNetworkAccessManager and the thing I want to analyze is which I catched through finished() signal of a reply from createRequest.

编辑:我上面提到的QIODevice实际上是QNetworkReply。我想创建一个代理来观察我的程序的请求和响应数据与QWebView访问一些Flash游戏。我实现了我的QNetworkAccessManager子类的createRequest,我要分析的东西是我通过createRequest的回复的finished()信号捕获的。

Edit2: I notice that this QIODevice is a sequential one so the size is unknown. But how to read the data without clearing it?

Edit2:我注意到这个QIODevice是顺序的,因此大小未知。但如何在不清除数据的情况下读取数据?

2 个解决方案

#1


1  

You can use QIODevice::seek and then read the data again
from seek documantion:

您可以使用QIODevice :: seek然后从seek documantion中再次读取数据:

For random-access devices, this function sets the current position to pos, returning true on success, or false if an error occurred. For sequential devices, the default behavior is to do nothing and return false.

对于随机访问设备,此函数将当前位置设置为pos,成功时返回true,如果发生错误则返回false。对于顺序设备,默认行为是不执行任何操作并返回false。

#2


0  

You can extract the size of the content directly from the QNetworkReply header using Qt like this:

您可以使用Qt直接从QNetworkReply标头中提取内容的大小,如下所示:

qlonglong size = reply->header(QNetworkRequest::ContentLengthHeader).toLongLong();

And then use that size with the peek function, example:

然后使用peek函数使用该大小,例如:

void DownloadManager::downloadFinished(QNetworkReply *reply)
{
    if (!reply->error())
    {
        bool ok;
        qlonglong size = reply->header(QNetworkRequest::ContentLengthHeader).toLongLong(&ok);

        if (ok)
        {
            QByteArray data = reply->peek(size); //Here lives your data without reset the internal buffer
            //Do something
        }
        else
        {
            qDebug() << "Could not read the header";
        }
    }

    //If you are ready then delete
    reply->deleteLater();
}

#1


1  

You can use QIODevice::seek and then read the data again
from seek documantion:

您可以使用QIODevice :: seek然后从seek documantion中再次读取数据:

For random-access devices, this function sets the current position to pos, returning true on success, or false if an error occurred. For sequential devices, the default behavior is to do nothing and return false.

对于随机访问设备,此函数将当前位置设置为pos,成功时返回true,如果发生错误则返回false。对于顺序设备,默认行为是不执行任何操作并返回false。

#2


0  

You can extract the size of the content directly from the QNetworkReply header using Qt like this:

您可以使用Qt直接从QNetworkReply标头中提取内容的大小,如下所示:

qlonglong size = reply->header(QNetworkRequest::ContentLengthHeader).toLongLong();

And then use that size with the peek function, example:

然后使用peek函数使用该大小,例如:

void DownloadManager::downloadFinished(QNetworkReply *reply)
{
    if (!reply->error())
    {
        bool ok;
        qlonglong size = reply->header(QNetworkRequest::ContentLengthHeader).toLongLong(&ok);

        if (ok)
        {
            QByteArray data = reply->peek(size); //Here lives your data without reset the internal buffer
            //Do something
        }
        else
        {
            qDebug() << "Could not read the header";
        }
    }

    //If you are ready then delete
    reply->deleteLater();
}