【问题标题】:custom QAbstractNetworkCache implementation; QAbstractNetworkCache::insert(QIODevice *device) device has no data自定义 QAbstractNetworkCache 实现; QAbstractNetworkCache::insert(QIODevice *device) 设备没有数据
【发布时间】:2013-12-26 22:39:47
【问题描述】:

我正在尝试构建自己的自定义 QAbstractNetworkCache 实现以与 QNetworkAccessManager 一起使用。

QAbstractNetworkCache::insert(QIODevice *device) 遇到问题;在这个方法中,设备总是带着 0 个字节到达。

据我了解,一旦QNetworkAccessManager 完成下载,从QAbstractNetworkCache::prepare(const QNetworkCacheMetaData &metaData) 返回的QIODevice* 将填充数据并用作QAbstractNetworkCache::insert(QIODevice *device) 方法的参数。

所以我准备了一个QBuffer 作为这个容器,但是每当QAbstractNetworkCache::insert(QIODevice *device) 被调用时,它总是会空无一物到达(device->bytesAvailable() == 0)

QIODevice* NetworkCachePrivate::prepare(const QNetworkCacheMetaData &metaData) {

        if (!metaData.isValid() || !metaData.url().isValid() || cacheDir.isEmpty()) return 0;

        QIODevice* device = 0;

        QString hash = hexMD5(metaData.url().toString());

        QScopedPointer<QBuffer> buffer(new QBuffer);

        if (buffer->open(QIODevice::ReadWrite))
        {
                qDebug() << "BUFFER READY";
                device = buffer.take();
                deviceMapping[device] = qMakePair(hash, metaData);
        }

        return device;
}

void NetworkCachePrivate::insert(QIODevice *device) {
        if (deviceMapping.contains(device))
        {
                QPair<QString, QNetworkCacheMetaData> pair = deviceMapping[device];
                QString fileName;
                fileName += cacheDir;
                fileName += QLatin1String("/");
                fileName += pair.first;

                qDebug() << "DEVICE BYTES" << device->bytesAvailable(); //ALWAYS 0!!!! :(
                QFile file(fileName);
                if (file.open(QIODevice::WriteOnly))
                {
                        qint64 size = file.write(device->readAll());
                        if (size <= 0)
                        {
                                file.remove();
                        }
                        else
                        {
                                qDebug() << "FILE WROTE " << size;
                                cacheSize += size;
                        }
                }
                deviceMapping.remove(device);
                delete device;
        }
}

QNetworkCacheMetaData NetworkCachePrivate::metaData (const QUrl &url ) {
    QString fileName;
    fileName += cacheDir; 
    fileName += QLatin1String("/"); 
    fileName += hexMD5(url.toString());

    QNetworkCacheMetaData data;

    if (!QFile::exists(fileName))
        return data;

    data.setUrl(url); 
    data.setExpirationDate(QDateTime::currentDateTime().addYears(1));
    return data;
}

【问题讨论】:

  • 你确定问题不在于QBuffer简单地返回0,因为它是一个随机访问I/O设备,它的当前位置在缓冲区的末尾(因为写入器刚刚填满它与数据)?
  • 嗯,可以。稍后将尝试寻找它的开始。
  • 是的,facepalm。这很明显:(。谢谢。
  • @peppe PS。您可能想复制评论作为答案,以便我能够接受。 :)

标签: c++ qt qt4.8 qtcore qiodevice


【解决方案1】:

正如 peppe 在评论中还指出的那样,您需要根据 documentation 在写入之后和读取之前寻找 QBuffer 的开头:

QBuffer 允许您使用 QIODevice 接口访问 QByteArray。 QByteArray 被视为标准的随机访问文件。示例:

QBuffer buffer;
char ch;

buffer.open(QBuffer::ReadWrite);
buffer.write("Qt rocks!");
*** buffer.seek(0); ***
buffer.getChar(&ch);  // ch == 'Q'
buffer.getChar(&ch);  // ch == 't'
buffer.getChar(&ch);  // ch == ' '
buffer.getChar(&ch);  // ch == 'r'

为了让您的代码更具体,您需要插入如下语句:

...
device.seek(0);
qDebug() << "DEVICE BYTES" << device->bytesAvailable(); //NOT 0 ANYMORE!!!! :)
...

【讨论】:

    猜你喜欢
    • 2011-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-26
    • 1970-01-01
    相关资源
    最近更新 更多