基于内存缓冲区的流媒体数据缓存排序(一)

C++ 专栏收录该内容
3 篇文章 0 订阅

C++ 实验
基于内存缓冲区的流媒体数据缓存排序(一)

基于内存缓冲区的流媒体数据缓存排序

要求:

针对一个流媒体节目的单线程下载进行处理;

节目数据包无丢失、无乱

将收到的数据包直接写入缓冲区,缓冲区长度无限定;

排好序的数据如果超过一定长度,如30KB(可设定),则输出到文件;

如果结束,将缓冲区中连续的数据写入文件;

实现要求

缓冲区类    

定义基于动态内存分配的缓冲区类,包括如下

数据成员:

•缓冲区,用于缓存数据(按偏移量写入,完成排序);
•记录缓冲区内收到的数据总量;
•缓冲区中数据在节目(文件)中的偏移量(缺了这项信息,无法写入文件);
•其他必要信息。

    成员函数:

•构造函数、析构函数
•数据接收函数
•数据输出函数

测试程序

模拟网络流媒体的数据流到达:

•设定数据来源多媒体文件(本地磁盘);
•从多媒体文件读取一块数据(长度不超多1500B),模拟网络数据包;
•模拟的网络数据包:包括节目ID、数据包偏移量、数据包长度;
•将数据包发送给排序缓存类。
•将文件的所有数据按上述方式读入并发送给排序缓存类
•最好用类实现(不要求)

提示:用随机数生成每个数据包的长度:256~1500 Bytes


源代码:

#include <iostream>
#include <cstdio>

using namespace std;

class StreamBuffer
{
public:
	StreamBuffer();
	int ReceiveDate(unsigned int offset, unsigned int bytes, char *pData);
	int ContinueBytes(unsigned int &iDataOffset, char* &pData);
	int RemoveData(int iBytes);
	//~StreamBuffer();

private:
    <span style="white-space:pre">	</span>char m_data[30*1024];//存数据的buffer,也可以用指针
	char *head_pointer;
	char *tail_pointer;
	
};

StreamBuffer::StreamBuffer()
{
	head_pointer = m_data;
	tail_pointer = m_data;
}

int StreamBuffer::ReceiveDate(unsigned int offset, unsigned int bytes, char *pData)
{
	int iBytes;
	for(iBytes = 0; iBytes < bytes; iBytes++)
	{
		*(tail_pointer++) = *(pData++) 
	}
	return iBytes;// bytes the buffer saved
}

int StreamBuffer::ContinueBytes(unsigned int &iDataOffset, char* &pData)
{	
	//返回缓冲区中,排好序的数据的长度(单位字节数)。并通过引用参数返回如下信息
	//iDataOffset: 排好序的数据块中第一个字节的偏移量数值
	//pData:数据指针
	
	int iContinueBytes = 0;
	// to do: ...
	return iContinueBytes;
};


int StreamBuffer::RemoveData(int iBytes)
{//从缓冲区中把数据"删除",返回删除的字节数
  int iBytesRemoved=0;

   // to do: ...
   //从缓冲区中把数据"删除"
   return iBytesRemoved;
};


int main()
{
	char srcfileName[500]="ProgramTest\\Childhood.mp3";
	char dstfileName[500]="E:\\temp\\result.mp3";
	
	FILE* fpSrcFile = NULL;
	FILE* fpDstFile = NULL;
	
	char Buf[1500*2];
	unsigned int iOffset;
	int iReadBytes = 0, iWantReadBytes;

    int  iContinueBytes;
    int iUseBytes;
	unsigned int iOutDataOffset;
	char  *pOutData;

	StreamBuffer MyBuffer;

	fpSrcFile = fopen(srcfileName, "rb");
	if( fpSrcFile == NULL )
	{
	  cout<<"Cann't open file: "<<srcfileName<<endl;
	  return 1;
	}

	fpDstFile = fopen(dstfileName, "wb");
	if( fpDstFile == NULL )
	{
	  cout<<"Cann't create file: "<< dstfileName <<endl;
	  return 2;
	}

	iOffset =  ftell(fpSrcFile);
	iWantReadBytes = 1024;
	iReadBytes = fread(Buf, 1, iWantReadBytes, fpSrcFile);
	while(iReadBytes > 0)
	{
	    MyBuffer.ReceiveDate(iOffset,iReadBytes,Buf);
	    iContinueBytes = MyBuffer.ContinueBytes(iOutDataOffset, pOutData);
        if(iContinueBytes > 1024) //示例数值,可以调整
	    {
	        iUseBytes = iContinueBytes - 100;//假设用了一部分
			fseek(fpDstFile,iOutDataOffset,SEEK_SET);
			fwrite(pOutData,iUseBytes,1,fpDstFile);
			MyBuffer.RemoveData(iUseBytes);
	    }


	    	iOffset =  ftell(fpSrcFile);
            iWantReadBytes =  iOffset%500+500;
            iReadBytes = fread(Buf, 1, iWantReadBytes, fpSrcFile);
	}

	//输入流结束,把缓冲区中所有排好序的数据取出
	iContinueBytes = MyBuffer.ContinueBytes(iOutDataOffset, pOutData);
    fseek(fpDstFile,iOutDataOffset,SEEK_SET);

    fwrite(pOutData,iContinueBytes,1,fpDstFile);

    fclose(fpDstFile);
    fclose(fpSrcFile);

	// 通过比较,源文件、程序结果文件是否一致,判断程序的正确性
	//可用的文件比对软件: UltraEdit中带的UltraCompare软件。
    return 0;
}

void FileMenu(char *readfile, char *writefiel)
{
	char read_path[500];
	char write_path[500];
	char read_
}


  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值