Recent

Author Topic: [Solved] Are Tstreams always better?  (Read 707 times)

Ten_Mile_Hike

  • New Member
  • *
  • Posts: 44
[Solved] Are Tstreams always better?
« on: March 23, 2023, 09:00:28 pm »
I always use Tstream constructs for file manipulations and I am just curious as to if there there exist scenarios where any of you find that the use of the old "Assignfile", "Blockread" etc... type of constructs might be preferred instead.

TIA
« Last Edit: March 31, 2023, 08:04:54 pm by Ten_Mile_Hike »

Warfley

  • Hero Member
  • *****
  • Posts: 1499
Re: Are Tstreams always better?
« Reply #1 on: March 23, 2023, 09:21:40 pm »
Well, what does better mean? With the procedural you have more magic, e.g.
Code: Pascal  [Select][+][-]
  1. var
  2.   fl: TextFile;
  3. begin
  4.   AssignFile(fl, 'filename');
  5.   Rewrite(fl);
  6.   WriteLn(fl, 42, ' Hello World', True, 3.14, enSomeEnumValue); // Writes an integerm string, boolean, float and enum value with a single command
  7. end;
This is simply not possible with streams.
Streams are therefore compatible with other streams:
Code: Pascal  [Select][+][-]
  1. var
  2.   fs: TFileStream;
  3.   ms: TMemoryStream;
  4.   ss: TSocketStream;
  5.   sl: TStringList;
  6. begin
  7.   ...
  8.   sl.LoadFromFile(fs); // No matter the type of stream, one method can use all
  9.   sl.LoadFromFile(ms); // No matter the type of stream, one method can use all
  10.   sl.LoadFromFile(ss); // No matter the type of stream, one method can use all

Also I personally like the subject.verb(objects) syntax more than the classical verb(subject, objects), as it is more closely to natural language.

I personally like the TStream based handling more, first I'm not a big fan of compiler magic, and file handling is full of it (not just the magic Read and Write function family, but also the type itself is heaviely abstracted by the compiler), and I just like when I use concepts where I know that I could build them myself if I wanted (e.g. if I needed some special functionality).
Also I think that it's clearer what they do when you write TFileStream.Create(name, mode), rather than having to first AssignFile and then using either Rewrite, Append or Reset. I don't like the concept of creating an object (using AssignFile), but that it is after creation still in an undefined state and I first need to do a second operation on it.
I like to have one function that does all the construction and initialization in one
« Last Edit: March 23, 2023, 09:29:34 pm by Warfley »

PascalDragon

  • Hero Member
  • *****
  • Posts: 5446
  • Compiler Developer
Re: Are Tstreams always better?
« Reply #2 on: March 23, 2023, 09:32:48 pm »
This is simply not possible with streams.

Well, that depends a bit on your definition of “possible” ;)

Code: Pascal  [Select][+][-]
  1. program tstrmio;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6.   StreamIO, Classes;
  7.  
  8. type
  9.   TEnum = (
  10.     enSomeEnumValue
  11.   );
  12.  
  13. var
  14.   f: TextFile;
  15.   ss: TStringStream;
  16. begin
  17.   ss := TStringStream.Create('');
  18.   try
  19.     AssignStream(f, ss);
  20.     Rewrite(f);
  21.     WriteLn(f, 42, ' Hello World', True, 3.14, enSomeEnumValue);
  22.     Close(f);
  23.     // will write: 42 Hello WorldTRUE 3.1400000000000001E+000enSomeEnumValue
  24.     Writeln(ss.DataString);
  25.   finally
  26.     ss.Free;
  27.   end;
  28. end.

I personally prefer streams in most situations as well however. :)

korba812

  • Sr. Member
  • ****
  • Posts: 392
Re: Are Tstreams always better?
« Reply #3 on: March 23, 2023, 10:04:15 pm »
Another difference is how I/O errors are handled. In the classic way of accessing files, you use IOResult function. For streams, exceptions are usually used.

Warfley

  • Hero Member
  • *****
  • Posts: 1499
Re: Are Tstreams always better?
« Reply #4 on: March 23, 2023, 10:31:54 pm »
But this is only if you disable IO checking via {$i-}.

Also for FileStreams that is not necessarily the case that they throw exceptions. For example when using raw Read/Write, you need to check the result if it is <(=) 0 for checking if an error occured. When using the Read/WriteBuffer functions (which are internally also used by the Helpers like ReadDWord or ReadByte and so on), then exceptions are throws.

Generally speaking, as much as the TStream API is nice for being so widely used throughout the RTL, FCL and LCL, error management with it can be a bit icky, as you either have to use Read/Write and do everything yourself (like handling incomplete buffers and so on), or you use Read/WriteBuffer, which takes care of that, but trows the exact same error type (EReadError with a constant message) on everything, even for a totally fine and non errorneous EOF. Which can be very annoying.

Especially that all exceptions are static make it quite annyoing.

 

TinyPortal © 2005-2018