外部内存上的QDataStream
QDataStream on external memory?
我想将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; }
我认为您可能需要实现QIODevice
,您可以很容易地制作一个非常简单的顺序设备。这是我很快拼凑出来的一个,我还没有检查它是否有效(请随意让它发挥作用并编辑帖子)。
class SimpleBuffer : public QIODevice
{
Q_OBJECT
public:
SimpleBuffer(char* begin, char* end):mBegin(begin),mEnd(end){}
virtual bool atEnd() const {return mEnd == mBegin; }
virtual bool isSequential() const { return true; }
protected:
virtual qint64 readData(char*, qint64) { return -1; }
virtual qint64 writeData(const char* data, qint64 maxSize)
{
const qint64 space = mEnd - mBegin;
const qint64 toWrite = qMin(maxSize, space);
memcpy(mBegin, data, size_t(toWrite));
mBegin += toWrite;
return toWrite;
}
private:
char* mBegin;
char* mEnd;
Q_DISABLE_COPY(SimpleBuffer)
};
也许来自RawData的作品:
QByteArray QByteArray::fromRawData(const char*data,int size)[static]
使用它类似于:
char* out=new char[enoughbytes]; // preallocate at suitable scope
QVector<int> in;
QByteArray ba=QByteArray::fromRawData(out,enoughbytes);
QDataStream stream(&ba,QIODevice::WriteOnly);
stream << in;
请注意,QDataStream在数据的开头添加了一些自己的数据(虽然不多),所以记住要为此预分配更多的数据,以及QVector序列化的任何其他数据。
为什么不使用QBuffer?
QByteArray myBuffer;
myBuffer.reserve(10000); // no re-allocation
QBuffer buffer(&myBuffer);
buffer.open(QIODevice::WriteOnly);
QDataStream out(&buffer);
out << QApplication::palette();
相关文章:
- 将字符串存储在c++中的稳定内存中
- C++ 指针的内存地址和指向数组的内存地址如何相同?
- Win32编译器选项和内存分配
- 当vector是tje全局变量时,c++中vector的内存管理
- 带内存和隔离功能的SQLite
- 是否可以通过C++扩展强制多个python进程共享同一内存
- 迭代时从向量和内存中删除对象
- 在C++中打印指向不同基元数据类型的指针的内存地址
- 这个指针和内存代码打印是什么?我不知道是打印垃圾还是如何打印我需要的值
- 多个文件的内存分配错误"在抛出 'std :: bad_alloc' what (): std :: bad_alloc 的实例后终止调用" [C++]
- 为什么示例代码访问IUnknown中已删除的内存
- 如何在C++类内存结构中创建"spacer"?
- 从构造函数抛出异常时如何克服内存泄漏
- malloc() 可能出现内存泄漏
- 如何理解将半精度指针转换为无符号长指针和相关的内存对齐
- 在调用FreeLibrary后,释放动态链接到具有相同版本的CRT堆的DLL的内存
- 如何针对特定情况调试和修复此双自由内存损坏问题
- 类型总是使用其大小存储在内存中吗
- 有没有一种方法可以测量c++程序的运行时内存使用情况
- 外部内存上的QDataStream