【发布时间】:2012-04-20 13:13:13
【问题描述】:
我想将 QVector 序列化为 char* 数组。我通过以下代码做到这一点:
QVector<int> in;
...
QByteArray bytes;
QDataStream stream(&bytes, QIODevice::WriteOnly);
stream << in;
std::copy(bytes.constData(), bytes.constData() + bytes.size(), out);
我保证out 足够大。由于此代码被非常频繁地调用,我想避免这种不必要的std::copy 操作,并使QByteArray 或QDataStream 在out 指向的预分配用户内存上工作。那可能吗?有什么好主意吗?
UPDATE:QByteArray::fromRawData() 不符合需求,因为它不允许更改创建它的 char* 缓冲区,换句话说, QByteArray 在首次修改此类创建的实例时执行深度复制。 像他们说的那样。 这确保了原始数据数组本身永远不会被 QByteArray 修改。
解决方案:@skyhisi 提出的解决方案完全符合我的需求。完整代码如下。
-
SimpleBuffer.hpp
#pragma once #include <QtCore/QIODevice> class SimpleBuffer : public QIODevice { Q_OBJECT Q_DISABLE_COPY(SimpleBuffer) public: SimpleBuffer(char* const begin, const char* const end) : _begin(begin), _end(end){} virtual bool atEnd() const { return _end == _begin; } virtual bool isSequential() const { return true; } protected: virtual qint64 readData(char*, qint64) { return -1; } virtual qint64 writeData(const char* const data, const qint64 maxSize) { const qint64 space = _end - _begin; const qint64 toWrite = qMin(maxSize, space); memcpy(_begin, data, size_t(toWrite)); _begin += toWrite; return toWrite; } private: char* _begin; const char* const _end; }; -
main.cpp
#include "SimpleBuffer.hpp" #include <QtCore/QVector> #include <QtCore/QDataStream> #include <QtCore/QByteArray> int main(int, char**) { QVector<int> src; src << 3 << 7 << 13 << 42 << 100500; const size_t dataSize = sizeof(quint32) + src.size() * sizeof(int); char* const data = new char[dataSize]; // prepare stream and write out the src vector { SimpleBuffer simpleBuffer(data, data + dataSize); simpleBuffer.open(QIODevice::WriteOnly); QDataStream os(&simpleBuffer); os << src; } // read vector with QByteArray QVector<int> dst; { const QByteArray byteArray = QByteArray::fromRawData((char*)data, dataSize); QDataStream is(byteArray); is >> dst; } delete [] data; // check we've read exactly what we wrote Q_ASSERT(src == dst); return 0; }
【问题讨论】: