是否有更好的方法来处理缓冲区和阅读中的不完整数据
Is there a better way to handle incomplete data in a buffer and reading?
我正在处理由事件构建的二进制文件。每个事件都可以具有可变长度。由于我的读取缓冲区是固定尺寸的,因此我处理的事情如下:
const int bufferSize = 0x500000;
const int readSize = 0x400000;
const int eventLengthMask = 0x7FFE0000;
const int eventLengthShift = 17;
const int headerLengthMask = 0x1F000;
const int headerLengthShift = 12;
const int slotMask = 0xF0;
const int slotShift = 4;
const int channelMask = 0xF;
...
//allocate the buffer we allocate 5 MB even though we read in 4MB chunks
//to deal with unprocessed data from the end of a read
char* allocBuff = new char[bufferSize]; //inFile reads data into here
unsigned int* buff = reinterpret_cast<unsigned int*>(allocBuff); //data is interpretted from here
inFile.open(fileName.c_str(),ios_base::in | ios_base::binary);
int startPos = 0;
while(!inFile.eof())
{
int index = 0;
inFile.read(&(allocBuff[startPos]), readSize);
int size = ((readSize + startPos)>>2);
//loop to process the buffer
while (index<size)
{
unsigned int data = buff[index];
int eventLength = ((data&eventLengthMask)>>eventLengthShift);
int headerLength = ((data&headerLengthMask)>>headerLengthShift);
int slot = ((data&slotMask)>>slotShift);
int channel = data&channelMask;
//now check if the full event is in the buffer
if( (index+eventLength) > size )
{//the full event is not in the buffer
break;
}
++index;
//further processing of the event
}
//move the data at the end of the buffer to the beginning and set start position
//for the next read
for(int i = index; i<size; ++i)
{
buff[i-index] = buff[i];
}
startPos = ((size-index)<<2);
}
我的问题是:在缓冲区末尾使用未加工的数据更好吗?
您可以使用圆形缓冲区而不是简单的数组来改进它。那是阵列上的圆形迭代器。那么,您就无需完成所有复制&mdash;阵列的"启动"移动。
除此之外,不,不是真的。
过去遇到这个问题时,我只是复制了未加工的数据降低,然后从末尾阅读。这是一个有效的解决方案(迄今为止最简单的话)元素很小,缓冲液很大。(在现代机器,"相当小"很容易成为几个一百kb。)当然,您必须跟踪多少您已经复制了,以调整指针和大小接下来阅读。
除此之外:
- 您最好使用
std::vector<char>
作为缓冲区。 - 您不能将四个字节从磁盘读取到一个
unsigned int
仅通过施放其地址;你必须插入每个字节中的每个字节都属于unsigned int
。 - 最后:您不检查阅读成功处理数据之前。使用未掩盖的输入与
istream
有点棘手:您的循环可能应该是就像是while ( inFile.read( addr, len ) || inFile.gcount() != 0 )...
。
相关文章:
- 通过套接字[TCP]传输数据 如何在C / C ++中打包多个整数并使用send() recv()传输数据
- 如果变量数据包含大于 vector 所有元素的整数,则仅在视觉工作室上接收"矢量下标超出范围"?
- 查找存储在二叉搜索树的所有非叶子中的数据总和?(返回整数的独立递归函数
- 整数数据如何以位为单位存储在内存中?不是右对齐吗?
- 什么是 16 字节有符号整数数据类型?
- 将整数的二进制数据转换为浮点数
- 如何对 int 变量应用验证,使其仅接受整数数据,并且在任何其他数据的情况下不会出错?
- C++11 中是否有实际的 4 位整数数据类型
- 错误 C2864:'element::next':只能在类 (STRUCT) 中初始化静态常量整数数据成员
- 1 字节整数数据类型
- 使用 MFC C++ 6.0 从 ms 访问中读取整数数据
- 需要帮助从文件中获取字符和整数数据
- 在整数数据类型和连续两个字符类型之后.第 2 个字符的数据类型跳过..为什么
- C++字符串 DD:HH:MM:SS 到整数数据类型
- 如何存储具有重复格式的整数数据
- 如何从二进制文件中读取位整数数据
- 布尔数据类型vs整数数据类型来表示真值
- 将2d数组整数数据从c++发送到qml
- 如果我将数字存储为整数数据类型,如何检查另一个数字中是否存在一个数字
- 超过 C++ 的最大整数数据类型