unit BufferedFileStream;
interface
uses
Classes;
type
TBufferedFileStream =
class(TFileStream)
const
MaxBufSize = 4096;
private
FBuffer:
array[0..Pred(MaxBufSize)]
of Byte;
FBufOffset: Int64;
FBufSize: Integer;
FDirty: Boolean;
protected
procedure MoveBuffer(
const NewOffset: Int64);
virtual;
procedure FlushBuffer;
virtual;
public
destructor Destroy;
override;
function Read(
var Buffer; Count: Longint): Longint;
override;
function Write(
const Buffer; Count: Longint): Longint;
override;
end;
implementation
{ TBufferedFileStream }
destructor TBufferedFileStream.Destroy;
begin
FlushBuffer;
inherited;
end;
procedure TBufferedFileStream.MoveBuffer(
const NewOffset: Int64);
begin
FlushBuffer;
FBufOffset:= NewOffset;
Seek(FBufOffset, soBeginning);
FBufSize:=
inherited Read(FBuffer, SizeOf(FBuffer));
end;
procedure TBufferedFileStream.FlushBuffer;
begin
if FDirty
then
begin
Seek(FBufOffset, soBeginning);
inherited Write(FBuffer, FBufSize);
FDirty:= False;
end;
end;
function TBufferedFileStream.
Read(
var Buffer; Count: Integer): Longint;
var
Offset: Int64;
Delta: Integer;
begin
if Count < MaxBufSize
then
begin
Offset:= Seek(0, soCurrent);
Delta:= Offset - FBufOffset;
if (Delta < 0)
or (Delta + Count > FBufSize)
then
begin
MoveBuffer(Offset);
Delta:= Offset - FBufOffset;
end;
Result:= FBufSize - Delta;
if Result > Count
then
Result:= Count;
if Result > 0
then
begin
Move(FBuffer[Delta], Buffer, Result);
end;
Seek(Offset + Result, soBeginning);
end else
Result:=
inherited Read(Buffer, Count);
end;
function TBufferedFileStream.
Write(
const Buffer; Count: Integer): Longint;
var
Offset: Int64;
Delta: Integer;
begin
if Count < MaxBufSize
then
begin
Offset:= Seek(0, soCurrent);
Delta:= Offset - FBufOffset;
if (Delta < 0)
or (Delta + Count > MaxBufSize)
then
begin
MoveBuffer(Offset);
Delta:= Offset - FBufOffset;;
end;
Result:= Count;
if FBufSize < Delta + Count
then
FBufSize:= Delta + Count;
if Result > 0
then
begin
Move(Buffer, FBuffer[Offset - FBufOffset], Result);
FDirty:= True;
end;
Seek(Offset + Result, soBeginning);
end else
Result:=
inherited Write(Buffer, Count);
end;
end.