2012-04-07 77 views
0

我想將QVector序列化成char *數組。我通過以下代碼執行此操作:QDataStream在外部存儲器上?

QVector<int> in; 
... 
QByteArray bytes; 
QDataStream stream(&bytes, QIODevice::WriteOnly); 
stream << in; 
std::copy(bytes.constData(), bytes.constData() + bytes.size(), out); 

我保證out足夠大。由於這段代碼經常被調用,所以我想避免這種不必要的std::copy操作,並且使QByteArrayQDataStream可以在由out指向的預先分配的用戶內存上工作。那可能嗎?任何想法?

UPDATE的QByteArray :: fromRawData()不匹配的需求導致它不允許改變字符*緩衝創建它上,換言之,上的QByteArray這種第一修改執行深層副本創建實例。 正如他們所說。 這確保原始數據數組本身永遠不會被QByteArray修改。

解決方案:@skyhisi提出的解決方案完全符合我的需求。完整的代碼如下。

  1. 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; 
    }; 
    
  2. 的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; 
    } 
    

回答

2

我認爲你可能需要實現一個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) 
}; 
+0

它像一個魅力,感謝你! – prokher 2012-04-30 17:25:59

+0

將您的解決方案添加到原始郵件。 – prokher 2012-04-30 17:46:05

0

也許fromRawData工作:

的QByteArray的QByteArray :: fromRawData(爲const char *的數據, 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序列化的任何附加數據。

+1

這是我最初的想法。但不幸的是'QByteArray'在第一次修改這樣創建的實例時執行深層複製。正如他們所說[這裏](http://qt-project.org/doc/qt-4.8/qbytearray.html#fromRawData)。 _This確保原始數據數組本身永遠不會被QByteArray修改._ – prokher 2012-04-07 14:52:00

0

爲什麼不使用QBuffer

QByteArray myBuffer; 
myBuffer.reserve(10000); // no re-allocation 

QBuffer buffer(&myBuffer); 
buffer.open(QIODevice::WriteOnly); 

QDataStream out(&buffer); 
out << QApplication::palette(); 
+0

因爲目標緩衝區('char * out')超出了我的控制範圍並且被外部庫分配。問題的實質是如何在不使用中間緩衝區的情況下將此外部內存包裝到QDataStream中。 – prokher 2015-09-12 12:51:05