Hello!

>> I could but...don't remember where is my stop-time watch I just bought
>> around the corner to make it pause life-time for next 10 years :-)

> However, most high level components would benefit from such a buffered
> stream,
> highly efficient, and don't forget "I am programming, therefore I exist"
> ;-)

I wrote a write-buffering stream. Anyone interested? Adding read and seek
support and extending it so it can write to other streams shouldn't be
difficult.

TWriteBufferedFileStream = class(TStream)
private
        FHandle: integer;
        FBuffer: pchar;
        FBufSize, FBufPos: longint;
public
        constructor Create(const FileName: string; Mode: Word);
        destructor Destroy; override;
        function Read(var Buffer; Count: Longint): Longint; override;
        function Seek(Offset: Longint; Origin: Word): Longint; override;
        function Write(const Buffer; Count: Longint): Longint; override;
        end;

[..]

function TWriteBufferedFileStream.Read(var Buffer; Count: Longint): Longint;
begin;
raise EInvalidOperation.Create('Read not implemented.');
end;

function TWriteBufferedFileStream.Seek(Offset: Longint; Origin: Word):
Longint;
begin;
raise EInvalidOperation.Create('Seek not implemented.');
end;

function TWriteBufferedFileStream.Write(const Buffer; Count: Longint):
Longint;
begin;
if count+FBufPos>FBufSize then
        begin;
        FileWrite(FHandle,FBuffer^,FBufPos);
        FBufPos:=0;
        end;
if count<FBufSize then
        begin;
        move(Buffer,FBuffer[FBufPos],count);
        inc(FBufPos,count);
        end
else
        FileWrite(FHandle,Buffer,Count);
result:=count;
end;

constructor TWriteBufferedFileStream.Create(const FileName: string; Mode:
Word);
begin;
FBufSize:=256*1024;
Getmem(FBuffer, FBufSize);
FBufPos:=0;
if Mode=fmCreate then
        begin
        FHandle:=FileCreate(FileName);
        if FHandle<0 then
                raise EFCreateError.CreateFmt('', [FileName]);
        end
else
        begin
        FHandle:=FileOpen(FileName, Mode);
        if FHandle<0 then
                raise EFOpenError.CreateFmt('', [FileName]);
        end;
end;

destructor TWriteBufferedFileStream.Destroy;
begin;
if FHandle>=0 then
        begin;
        if FBufPos>0 then
                FileWrite(FHandle,FBuffer^,FBufPos);
        FileClose(FHandle);
        end;
Freemem(FBuffer);
Inherited Destroy;
end;


Please note that this stream type is write-only (ie. intended to optimize
writing files in small chunks, like those downloaded by TFTPCli or THTTPCli)
and its worst case is calling Write with count close to the FBufSize
(hard-coded for 256kB). And there's no "flush" method - so you can't forget
to .free/.destroy this stream as soon as possible, otherwise data stored in
internal FBuffer won't be written to disk (if application crashes, these
data will be lost).


Also please note that although you'll see significant speedups when writing
in smaller than 256/512-byte chunks, it's still a bad idea to do so (if you
have any possibilities to reduce .writes, use them) - writing in 1-kilobyte
chunks is still faster than in 1-byte chunks. Actually chunk sizes
should be a multiplies of 4 (try to disassemble Move procedure, you'll
see why).

-- 
Piotr "Hellrayzer" Dalek
[EMAIL PROTECTED]

----------------------------------------------------------------------
Startuj z INTERIA.PL! >>> http://link.interia.pl/f186c 

-- 
To unsubscribe or change your settings for TWSocket mailing list
please goto http://www.elists.org/mailman/listinfo/twsocket
Visit our website at http://www.overbyte.be

Reply via email to