环形缓冲区实现类(Delphi)
2014-04-01 11:35
615 查看
环形缓冲区的用途及原理可以去百度资料狠多的,这里就不介绍了。直接贴代码.代码分别用D7,XE2编译测试
源码下载 http://files.cnblogs.com/lwm8246/uCircleBuffer.rar
测试代码段:
源码下载 http://files.cnblogs.com/lwm8246/uCircleBuffer.rar
//环形缓冲区实现类 //2014-03-20 16:20 //QQ 287413288 unit uCircleBuffer; interface uses Windows,Classes; type TCircleBuffer=class private FMS:TMemoryStream; FUserData:Pointer; function GetMemory: Pointer; protected FReadPosition:Integer; FWritePosition:Integer; FCanReadCount:Integer; FCanWrieCount:Integer; public constructor Create(const BuffSize:Integer);virtual; destructor Destroy();override; function Write(const Buffer;Count:Integer):integer;virtual; function Read(var Buffer;Count:Integer):Integer;virtual; public property ReadPosition:Integer read FReadPosition; property WritePosition:Integer read FWritePosition; property CanReadCount:Integer read FCanReadCount; property CanWrieCount:Integer read FCanWrieCount; property Memory:Pointer read GetMemory; property UserData:Pointer read FUserData write FUserData; end; //线程安全版本 TCircleBufferThread=class(TCircleBuffer) private FCS:TRTLCriticalSection; function GetReadPosition():Integer; function GetWritePosition():Integer; function GetCanReadCount():Integer; function GetCanWrieCount():Integer; public constructor Create(const BuffSize:Integer);override; destructor Destroy();override; function Write(const Buffer;Count:Integer):integer;override; function Read(var Buffer;Count:Integer):Integer;override; public property ReadPosition:Integer read GetReadPosition; property WritePosition:Integer read GetWritePosition; property CanReadCount:Integer read GetCanReadCount; property CanWrieCount:Integer read GetCanWrieCount; end; implementation { TCircleBuffer } constructor TCircleBuffer.Create(const BuffSize: Integer); begin FMS := TMemoryStream.Create(); FMS.Size := BuffSize; FMS.Position := 0; FWritePosition := 0; FReadPosition := 0; FCanWrieCount := BuffSize; FCanReadCount := 0; //\\ ZeroMemory(FMS.Memory,FMS.Size); end; destructor TCircleBuffer.Destroy; begin inherited; FMS.Free(); end; function TCircleBuffer.GetMemory: Pointer; begin Result := FMS.Memory; end; function TCircleBuffer.Read(var Buffer; Count: Integer): Integer; var P:PAnsiChar; Len,DataLen:Integer; begin Result := 0; //(I) if FCanReadCount <= 0 then begin Exit; end; if Count > FCanReadCount then DataLen := FCanReadCount else DataLen := Count; FMS.Position := FReadPosition mod FMS.Size; Result := FMS.Read(Buffer,DataLen); Dec(FCanReadCount,Result); Dec(Count,Result); //(II) if (Count > 0) and (FCanReadCount > 0) then //继续读 begin DataLen := Count; if DataLen > FCanReadCount then DataLen := FCanReadCount; FMS.Position := 0; P := @Buffer; Inc(P,Result); Len := FMS.Read(P^,DataLen); Inc(Result,Len); Dec(FCanReadCount,Len); end; //增加可写字节数 Inc(FCanWrieCount,Result); if FCanWrieCount > FMS.Size then FCanWrieCount := FMS.Size; //调整读指针位置 Inc(FReadPosition,Result); if FReadPosition > FMS.Size then Dec(FReadPosition,FMS.Size); end; function TCircleBuffer.Write(const Buffer; Count: Integer): integer; var Len,DataLen:Integer; P:PAnsiChar; begin Result := 0; //(I) if FCanWrieCount <= 0 then begin Exit; end; if Count > FCanWrieCount then DataLen := FCanWrieCount else DataLen := Count; FMS.Position := FWritePosition mod FMS.Size; P := @Buffer; Result := FMS.Write(Buffer,DataLen); P := FMS.Memory; if P = nil then Exit; Dec(Count,Result); Dec(FCanWrieCount,Result); if (Count > 0) and (FCanWrieCount > 0) then begin //(II) P := @Buffer; Inc(P,Result); Len := FReadPosition - 0; if Count > Len then DataLen := Len else DataLen := Count; FMS.Position := 0; Len := FMS.Write(P^,DataLen); Inc(Result,Len); Dec(FCanWrieCount,Len); end; //增加可读字节数 Inc(FCanReadCount,Result); if FCanReadCount > FMS.Size then FCanReadCount := FMS.Size; //调整写指针位置 Inc(FWritePosition,Result); if FWritePosition > FMS.Size then FWritePosition := FWritePosition - FMS.Size; end; { TCircleBufferThread } constructor TCircleBufferThread.Create(const BuffSize: Integer); begin InitializeCriticalSection(FCS); //初始化 inherited Create(BuffSize); end; destructor TCircleBufferThread.Destroy; begin DeleteCriticalSection(FCS); inherited; end; function TCircleBufferThread.GetCanReadCount: Integer; begin EnterCriticalSection(FCS); Result := FCanReadCount; LeaveCriticalSection(FCS); end; function TCircleBufferThread.GetCanWrieCount: Integer; begin EnterCriticalSection(FCS); Result := FCanWrieCount; LeaveCriticalSection(FCS); end; function TCircleBufferThread.GetReadPosition: Integer; begin EnterCriticalSection(FCS); Result := FReadPosition; LeaveCriticalSection(FCS); end; function TCircleBufferThread.GetWritePosition: Integer; begin EnterCriticalSection(FCS); Result := FWritePosition; LeaveCriticalSection(FCS); end; function TCircleBufferThread.Read(var Buffer; Count: Integer): Integer; begin EnterCriticalSection(FCS); try Result := inherited read(Buffer,Count); finally LeaveCriticalSection(FCS); end; end; function TCircleBufferThread.Write(const Buffer; Count: Integer): integer; begin EnterCriticalSection(FCS); try Result := inherited Write(Buffer,Count); finally LeaveCriticalSection(FCS); end; end; end.
测试代码段:
procedure TForm1.btn1Click(Sender: TObject); var obj:TCircleBuffer; TmpStr:AnsiString; Len:Integer; Buf:array[1..4096] of AnsiChar; ASize,APosition:Integer; P:PAnsiChar; begin obj := TCircleBuffer.Create(10); ZeroMemory(@Buf,SizeOf(Buf)); TmpStr := '0123456789'; Len := obj.Write(TmpStr[1],Length(TmpStr)); P := Obj.Memory; if P = nil then Exit; TmpStr := 'ABCD'; Len := obj.Write(TmpStr[1],Length(TmpStr)); if Len < 0 then Exit; P := Obj.Memory; if P = nil then Exit; TmpStr := '0123456789'; Len := obj.Read(Buf,10); if Len < 0 then Exit; P := Obj.Memory; if P = nil then Exit; Len := obj.Read(Buf,10); if Len < 0 then Exit; P := Obj.Memory; if P = nil then Exit; tmpStr := 'ABC'; Len := Obj.Write(TmpStr[1],3); if Len < 0 then Exit; tmpStr := '123456#'; Len := Obj.Write(TmpStr[1],Length(TmpStr)); if Len < 0 then Exit; P := Obj.Memory; if P = nil then Exit; FillChar(Buf,SizeOf(Buf),$32); // ZeroMemory(@Buf,SizeOf(Buf)); Len := obj.Read(Buf,3); if Len < 0 then Exit; ZeroMemory(@Buf,SizeOf(Buf)); Len := obj.Read(Buf,10); if Len < 0 then Exit; P := Obj.Memory; if P = nil then Exit; TmpStr := 'AB'; Len := obj.Write(TmpStr[1],2); if Len < 0 then Exit; P := Obj.Memory; if P = nil then Exit; TmpStr := 'abcdefghijklmnopqrst'; Len := obj.Write(TmpStr[1],Length(TmpStr)); if Len < 0 then Exit; ZeroMemory(@Buf,SizeOf(Buf)); Len := obj.Read(Buf,10); if Len < 0 then Exit; if obj <> nil then obj.Free(); P := Obj.Memory; if P = nil then Exit; end;
相关文章推荐
- linux 管道的环形buffer(缓冲区) 实现原理
- 环形缓冲区的实现原理(ring buffer)
- 环形缓冲区的实现
- 嵌入式 环形缓冲区的设计与实现
- 设备驱动中环形缓冲区数据存储和读写同步的实现
- 服务器公共组件实现 -- 环形缓冲区
- 环形缓冲区的实现原理(ring buffer)
- 环形缓冲区的设计与实现
- 架构设计:生产者/消费者模式 第6页:环形缓冲区的实现
- 架构设计:生产者/消费者模式 第6页:环形缓冲区的实现
- linux下C语言实现多线程通信—环形缓冲区,可用于生产者(producer)/消费者(consumer)【转】
- stm32F4 串口DMA+环形缓冲区的实现
- 服务器公共组件实现 -- 环形缓冲区
- EasyRTMP实现RTMP异步直播推送之环形缓冲区设计
- 环形缓冲区的设计与实现
- 环形缓冲区的实现原理
- EasyRTMP实现RTMP异步直播推送之环形缓冲区设计
- 环形缓冲区(JAVA数组实现)
- 环形缓冲区的实现原理与例程
- 环形缓冲区的C语言实现