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的大小呢?
- 恩,一旦调用该成员,将会在堆上分配一个指定大小的字符数组。
本文深入探讨Qt的QBuffer、QIODevicePrivateLinearBuffer、QRingBuffer和QByteDataBuffer等I/O设备与缓冲区类的功能、用法及应用场景。
2万+





