[fpc-devel] TBufferedFileStream

Michael Van Canneyt michael at freepascal.org
Sun Sep 4 14:51:43 CEST 2016



On Sun, 4 Sep 2016, José Mejuto wrote:

> El 04/09/2016 a las 14:04, Michael Van Canneyt escribió:
>
>>> The second powerful reason is that I was not aware about TBufStream :)
>> It's even documented.
>> http://www.freepascal.org/docs-html/current/fcl/bufstream/index.html
>
> Hello,
>
> Sure :) But I'm not aware about all the gems in fpc code :)
>
>>> TBufStream does support seek ? And SetSize ?
>> Seek: yes. Setsize not.
>
> I was asking looking at code:
>
> function TWriteBufStream.Seek(const Offset: Int64; Origin: TSeekOrigin): 
> Int64;
> begin
>  if (Offset=0) and (Origin=soCurrent) then
>    Result := FTotalPos
>  else
>    BufferError(SErrInvalidSeek);
> end;
>
> Maybe I'm missing something ?
>
> On the SetSize side I think there is a missing check, SetSize can make the 
> file smaller, so think in a 1 Kb file, you read the first byte so the buffer 
> will be filled with the 1 Kb data, now you SetSize to 1 byte and read another 
> byte, this read will return 1 byte success read which is out of the bounds of 
> the file.
> I know this is a terrible border case and the solution could be just 
> invalidate buffer when a SetSize is called.
>
>> The TBufStream class has 2 descendents: one for reading, one for writing.
>> This means the implementation is much more simple, and for most
>> usecases, this is sufficient.
>
> That's more or less what I was using in other programs, with my own class (I 
> should read more docs).
>
>>> My code like TBufStream inherits from TStream. Which is the advantage
>>> of inherit from TOwnerStream ?
>> TOwnerStream is only useful if you have a second stream which you use as a
>> source. It will free it for you. This is useful when chaining streams.
>
> Oh! I see, I'm using the typical Create(Stream,Owned=true)
>
>> I will add your implementation to the bufstream unit. It offers more
>> functionality, but works only on files.
>> 
>> It's - as usual - a tradeoff.
>
> Not exactly, it is possible to add my original implementation TCacheStream 
> which works over any TStream and create a TBufferedFileStream (for Delphi 
> compat.) inheriting from it, but it will not have the same inheritance chain.
>
> What's the best for fpc ? A generic stream cache, a inheritance compatible 
> TBufferedFileStream ? Or maybe both ? Or None ? :)

Generic stream cache. 
If you can rework your implementation to replace TBufStream, that would be absolutely superb !

We can keep the 2 descendents for backwards compatibility.

Michael.


More information about the fpc-devel mailing list