I'm having a headache trying to understand how all these streams are supposed to be used, even for a simple task like line oriented text read/write. I did solve the problem at hand but it feels clunky and probably wrong.
If there is a comprehensive 'streams in free pascal' tutorial somewhere please direct me to the proper RTFM department, I didn't find it myself.
What I'm doing right now: I want to write procedures/methods that take a TStream (any of them) and read/write text from/to it, be it a TFileStream or TStringStream or whatever (in practice, only those two, but I'm interested in the general case for learning). Text I/O is mostly line oriented (but I might want to write a line 'in parts' as opposed to building up the complete line and writing it at once, or read n characters ahead). Said procedures/methods are recursive (they deal with a hierarchical structure stored as text and expect it to be correct, no sophisticated parsing nor error detection is done apart from checking EOF). One is called 'Load' and one 'Save'. I gave up on 'Load' taking a TStream to avoid wrapping it in a TTextReader (but which one?) on every recursive call, so it's
Load(source: TTextReader)
and I call it with
Load(TStreamReader.Create(TFileStream.Create(filename,fmOpenRead)))
(but it could be a string in memory instead of a file). Writing is even more of a kludge:
does take a TStream as I'd like, but I resorted to writing with
dest.Write(s[1],Length(s));
. Again, it works but feels wrong. I know I could work around the problem altogether, for instance always writing the whole text to a string or TStringList and then dumping it to file if it needs be, or testing 'if mystream is TFileStream then...else...', but I'm looking for the clean, 'right way' to do it. I looked at the docs, but they don't say much beyond repeating the inheritance of the classes and the signatures of the methods with a scanty description, in the end I have more questions than answers.
Am I correct to assume Free Pascal classes mirror Delphi ones, to the point its docs also apply here?
Why is there a TTextReader but no TTextWriter?
What is the difference between using TStringReader and instead TStreamReader.Create(TStringStream(...))?
What is the difference between a TStringStream and a TMemoryStream?
What happens if my text is unicode?
I see there is a StreamIO unit which I discovered too late and haven't tried yet. It seems like the way to go, is it?
If so, how does it handle text which might be utf8? (let's say I don't care all the other encodings beyond ascii and utf8) Or should I use TCharEncStream? The two of them together somehow?
Also I'm not sure I understand how I'm supposed to use the StreamIO (ok, this will perhaps become clear once I actually try it in code): it seems to me I would declare a 'dummy' file variable, call StreamIO's 'Assign' on it, then read/write the file variable knowing that actually StreamIO will take over and do its thing, is that correct?
Thanks to all and sorry for the long post.