概述
在C/C++中,字节流是一种基本的数据处理方式,它涉及将数据视为连续的字节序列进行读取、写入或传输。字节流不关心数据的具体类型或结构,只关心字节的顺序和值。这种处理方式对于跨平台数据交换、网络通信、文件存储等场景非常有用。
在C语言中,字节流通常通过文件I/O函数和标准I/O库来处理。比如,我们可以使用fread和fwrite函数来读取和写入字节流。在C++中,我们可以使用标准库中的istream和ostream类来处理字节流,特别是通过ifstream和ofstream类来处理文件中的字节流。但如果需要创建自定义的字节流或者进行更复杂的低级别数据传输,可能会涉及网络编程或自定义内存缓冲区管理。
CHP_ByteStreamComposer类
为了使用面向对象的方式向上层提供简单、易用、统一的接口,我们需要封装自己的字节流合成器。字节流合成器一般用于网络通信时,合成自定义数据,支持添加整型数据、浮点型数据、字符串、buffer和对齐等。CHP_ByteStreamComposer类的头文件,可参考下面的示例代码。
class CHP_ByteStreamComposer { public: CHP_ByteStreamComposer(); ~CHP_ByteStreamComposer(); enum IHPByteOrderType { HPByteOrderType_Default, HPByteOrderType_ForceHost, HPByteOrderType_ForceNetwork }; bool Init(int nStreamLen, char *pStream = NULL, bool bNetworkByteOrder = false); char *GetStream(); int GetStreamLen(); int GetCurPos(); bool AddChar(unsigned char ucData); bool AddShort(unsigned short usData, IHPByteOrderType type = HPByteOrderType_Default); bool AddInt(unsigned int uiData, IHPByteOrderType type = HPByteOrderType_Default); bool AddInt64(HP_U64 ui64Data, IHPByteOrderType type = HPByteOrderType_Default); bool AddFloat(float fData); bool AddDouble(double dbData); bool AddStr(const char *pszData); bool AddBuf(void *pBuf, int nBufLen); bool AddPad(int nPad); bool Skip(int nLen); void Reset(); private: bool CheckAdd(int nLen); private: bool m_bAlloced; char *m_pStream; int m_nStreamLen; int m_nCurPos; bool m_bNetworkByteOrder; };
在上面的示例代码中,我们声明了一个枚举类型IHPByteOrderType。添加多字节数据时,可以指定字节序类型为以下三种。
HPByteOrderType_Default:默认字节序,以Init函数中传入的字节序为准。
HPByteOrderType_ForceHost:强制本地字节序。
HPByteOrderType_ForceNetwork:强制网络字节序。
下面,我们逐个介绍CHP_ByteStreamComposer类导出的公共接口。
Init:初始化函数。参数nStreamLen为要合成的流的长度;参数pStream为要合成的流的指针,传NULL时,由内部自动分配和释放;bNetworkByteOrder表示添加数据时,是否使用网络字节序;返回值为true表示成功,否则失败。
GetStream:获取流的指针。返回值为流的指针。
GetStreamLen:获取流的长度。返回值为流的长度。
GetCurPos:获取流中添加数据的当前位置。返回值为流中添加数据的当前位置。
AddChar:添加字符数据。参数ucData为字符数据,返回值为true表示成功,否则失败。
AddShort:添加短整型数据。参数usData为短整型数据,参数type为字节序类型,返回值为true表示成功,否则失败。
AddInt:添加整型数据。参数uiData为整型数据,参数type为字节序类型,返回值为true表示成功,否则失败。
AddInt64:添加64位整型数据。参数ui64Data为64位整型数据,参数type为字节序类型,返回值为true表示成功,否则失败。
AddFloat:添加单精度浮点型数据。参数fData为单精度浮点型数据,返回值为true表示成功,否则失败。
AddDouble:添加双精度浮点型数据。参数dbData为双精度浮点型数据,返回值为true表示成功,否则失败。
AddStr:添加字符串型数据。参数pszData为字符串型数据,返回值为true表示成功,否则失败。
AddBuf:添加buffer数据。参数pBuf为buffer数据,参数nBufLen为buffer数据长度,返回值为true表示成功,否则失败。
AddPad:添加对齐。假如当前位置为11,若nPad为4,则会添加1个字节的对齐;若nPad为8,则会添加5个字节的对齐。参数nPad为对齐字节数,返回值为true表示成功,否则失败。
Skip:跳过指定长度的数据。参数nLen为要跳过数据的长度,返回值为true表示成功,否则失败。
Reset:重置流,重置后,所有数据清零,且当前位置也为零,可以重新开始合成流。
总结
在处理跨平台的数据交换或网络通信时,字节流的重要性更加突出。不同的系统可能有不同的字节序(大端序或小端序),因此在发送和接收字节流时,可能需要考虑字节序的转换。此外,还需要确保数据的对齐和填充符合通信协议的要求。在网络通信中,字节流通常通过套接字进行传输。