Qt中的和字节流有关的几个Buffer类

来源:互联网 发布:柴鸡蛋逆袭网络剧 编辑:程序博客网 时间:2024/06/04 01:00

QBuffer

这是Qt的一个公有类,manual中说得很清楚:

  • 为QByteArray提供了一个QIODevice的接口,使得该QByteArray可以作为一个random-accessed的普通文件对待。

所以,此处没多少可说的了。一个具体的例子(同样取自Qt的manual):

QImage image;QByteArray ba;QBuffer buffer(&ba);buffer.open(QIODevice::WriteOnly);image.save(&buffer, "PNG"); // writes image into ba in PNG format

QIODevicePrivateLinearBuffer

私有类 ./src/corelib/io/qiodevice_p.h

一个线性缓冲区,从头部读取数据,从尾部追加数据,也可以在头部插入数据。

class QIODevicePrivateLinearBuffer{public:    QIODevicePrivateLinearBuffer(int);    ~QIODevicePrivateLinearBuffer();    void clear();    int size() const;    bool isEmpty() const;    void skip(int n);    int getChar();    int read(char* target, int size);    char* reserve(int size);    void chop(int size);    QByteArray readAll();    int readLine(char* target, int size);    bool canReadLine() const;    void ungetChar(char c);    void ungetBlock(const char* block, int size);};
  • ungetChar()/ungetBlock() 用来向缓冲区头部追加数据
  • reserve() 用来在尾部申请新的空间,并返回指针
    • 一般需要配合chop() 使用,比如申请10个字节空间,只写入8个字节。需要chop(2)
  • getChar()/read()/readAll()/readLine() 从头部读取数据

QRingBuffer

私有类 ./src/corelib/tools/qringbuffer_p.h

一个环形buffer,在尾部追加数据,从头部读取数据。适合用作IO的缓冲区

class QRingBuffer{public:    inline QRingBuffer(int growth = 4096);    inline const char *readPointer() const;    inline const char *readPointerAtPosition(qint64 pos, qint64 &length) const;    inline void free(int bytes);    inline char *reserve(int bytes);    inline void truncate(int pos);    inline void chop(int bytes);    inline bool isEmpty() const;    inline int getChar();    inline void putChar(char c);    inline void ungetChar(char c);    inline int size() const;    inline void clear();    inline int indexOf(char c) const;    inline int indexOf(char c, int maxLength) const;    inline int read(char *data, int maxLength);    inline QByteArray read(int maxLength);    inline QByteArray readAll();    inline QByteArray read();    inline void append(const QByteArray &qba);    inline QByteArray peek(int maxLength) const;    inline int skip(int length);    inline int readLine(char *data, int maxLength);    inline bool canReadLine() const;};

这个类挺复杂,不过多数成员函数,从名字上能猜个大概。

作为常规使用,我们需要从buffer中读取数据,可以使用:

  • read()/readLine()/readAll()/getChar()

读数比较简单,而如何添加数据,有点不太直观

  • 申请空间 reserve(),可得到一个指针
  • 借助该指针,往空间写入数据 ...
  • 如果申请了10个字节,而只写了8个字节,一定要用 chop() 切掉后面2个。

本来应该可以直接使用 append() 直接追加数据的,但是由于bug的存在,工作得并不好。

另外:ungetChar()/putChar() 分别是在缓冲区头部和尾部放置一个字符。

注:QRingBuffer内部是使用QList<QByteArray>构架的缓冲区。这样一来可以方便地在头部或尾部插入新的QByteArray.

QByteDataBuffer

Qt的私有类 ./src/corelib/tools/qbytedata_p.h

  • this class handles a list of QByteArrays. It is a variant of QRingBuffer that avoid malloc/realloc/memcpy.

class QByteDataBuffer{public:    QByteDataBuffer();    ~QByteDataBuffer();    inline void append(QByteDataBuffer& other);    inline void append(const QByteArray& bd);    inline void prepend(QByteArray& bd);    inline QByteArray read();    inline QByteArray readAll();    inline QByteArray read(qint64 amount);    qint64 read(char* dst, qint64 amount);    inline char getChar();    inline void clear();    inline qint64 byteAmount() const;    inline qint64 bufferCount() const;    inline bool isEmpty() const;    inline qint64 sizeNextBlock() const;    inline QByteArray& operator[](int i);    inline bool canReadLine() const;};

接口比 QRingBuffer 清晰很多,也更易用。

QDataBuffer

私有的Qt的模板类:./src/gui/painting/qdatabuffer_p.h

template <typename Type> class QDataBuffer{public:    QDataBuffer(int res);    ~QDataBuffer();    inline void reset();    inline bool isEmpty() const;    inline int size() const;    inline Type *data() const;    inline Type &at(int i);    inline const Type &at(int i) const;    inline Type &last();    inline const Type &last() const;    inline Type &first();    inline const Type &first() const;    inline void add(const Type &t);    inline void pop_back();    inline void resize(int size);    inline void reserve(int size);    inline void shrink(int size);;    inline void swap(QDataBuffer<Type> &other);    inline QDataBuffer &operator<<(const Type &t);};

模板函数,可返回首尾数据。

  • first()
  • last()

追加和弹出数据,每次一个

  • add()
  • pop_back()

调整缓冲区

  • resize()
  • reserve()
  • shrink()

QTestCharBuffer

一个私有类: src/testlib/qabstracttestlogger_h

这个东西似乎没有什么功能。分配一个buffer,可以改变其大小,可以获取首地址。仅次而已?

struct QTestCharBuffer{    inline QTestCharBuffer();    inline ~QTestCharBuffer();    inline char *data();    inline char **buffer();    inline const char* constData() const;    inline int size() const;    inline bool reset(int newSize);};

类内在栈上分配了一个固定大小512的字符数组:

  • data()/constData() 返回字符数组首地址
  • size() 返回字符数组的大小

前面说字符数组分配在栈上,但是为什么有一个reset()来改变buffer的大小呢?

  • 恩,一旦调用该成员,将会在堆上分配一个指定大小的字符数组。

原创粉丝点击