Recent

Author Topic: TFileStream.Create requires MODE in Lazarus  (Read 1782 times)

Atak_Snajpera

  • New Member
  • *
  • Posts: 31
TFileStream.Create requires MODE in Lazarus
« on: June 01, 2024, 02:21:32 pm »
What value should I use for MODE?

Delphi 7 code
Code: Pascal  [Select][+][-]
  1. function TWorkerThread.TransferData(FileName:string;TransferMode:TTransferMode):boolean;
  2. var BytesTransferred: Integer;
  3.     DataArray: array of byte;
  4.     FlagsAndAttributes: DWORD;
  5.     FileHandle: THandle;
  6.     Stream: TFileStream;
  7.     SumOfBytesTransferred:int64;
  8.     x:integer;
  9. begin
  10.  
  11.   Result:=false;
  12.  
  13.   if BufferedIO=false then FlagsAndAttributes:=FILE_FLAG_NO_BUFFERING
  14.   else FlagsAndAttributes:=FILE_ATTRIBUTE_NORMAL;
  15.  
  16.   if TransferMode=WRITE_DATA then FileHandle:=CreateFile(PChar(FileName), GENERIC_WRITE, FILE_SHARE_WRITE, nil,CREATE_ALWAYS, FlagsAndAttributes, 0)
  17.   else FileHandle:=CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ, nil,OPEN_EXISTING, FlagsAndAttributes, 0);
  18.  
  19.   if FileHandle=INVALID_HANDLE_VALUE then exit;
  20.  
  21.   SetLength(DataArray,BufferSize);
  22.   if TransferMode=WRITE_DATA then for x:=0 to BufferSize-1 do DataArray[x]:=Random(256);
  23.  
  24.   SumOfBytesTransferred:=0;
  25.   Stream:=TFileStream.Create(FileHandle)
  26.  
  27.   try
  28.  
  29.     repeat
  30.       if TransferMode=WRITE_DATA then BytesTransferred:=Stream.Write(DataArray[0],BufferSize)
  31.       else BytesTransferred:=Stream.Read(DataArray[0],BufferSize);
  32.  
  33.       SumOfBytesTransferred:=SumOfBytesTransferred+BytesTransferred;
  34.  
  35.       EnterCriticalSection(CriticalSection);
  36.       ProgressArray[ThreadIndex]:=SumOfBytesTransferred;
  37.       LeaveCriticalSection(CriticalSection);
  38.  
  39.     until (BytesTransferred<BufferSize) or (SumOfBytesTransferred=TransferSize) or (Terminated=true);
  40.  
  41.   finally
  42.  
  43.     Stream.Free;
  44.     if SumOfBytesTransferred=TransferSize then Result:=true;
  45.  
  46.   end;
  47.  
  48. end;          

Now Lazarus requires also a MODE.
Stream:=TFileStream.Create(FileHandle)
IOSpeedTester.lpr(518,41) Error: Wrong number of parameters specified for call to "Create"

Code: Pascal  [Select][+][-]
  1. constructor TFileStream.Create(const AFileName: string; Mode: Word);  
« Last Edit: June 01, 2024, 02:28:39 pm by Atak_Snajpera »

wp

  • Hero Member
  • *****
  • Posts: 13334
Re: TFileStream.Create requires MODE in Lazarus
« Reply #1 on: June 01, 2024, 02:50:44 pm »
What value should I use for MODE?

Depending on what you want to do: fmCreate, fmOpenRead, fmOpenWrite, fmOpenReadWrite, plus optionally sharing restrictions, e.g. fmShareDenyNone (no restrictions), fmShareDenyWrite (other cannot write) etc - see https://lazarus-ccr.sourceforge.io/docs/rtl/classes/tfilestream.create.html

Atak_Snajpera

  • New Member
  • *
  • Posts: 31
Re: TFileStream.Create requires MODE in Lazarus
« Reply #2 on: June 01, 2024, 03:02:23 pm »
Why do I have to add anything if lazarus shows this hint?

https://i.postimg.cc/RF1sCXWh/Untitled-1.png

Atak_Snajpera

  • New Member
  • *
  • Posts: 31
Re: TFileStream.Create requires MODE in Lazarus
« Reply #3 on: June 01, 2024, 03:28:32 pm »
Ok. Looks like THandleStream must to be used in lazarus instead of TFileStream in this case.

Thaddy

  • Hero Member
  • *****
  • Posts: 18676
  • Jungle wars. And failing health it seems.
Re: TFileStream.Create requires MODE in Lazarus
« Reply #4 on: June 01, 2024, 03:41:56 pm »
No, THandleStream is the ancestor: that is called OOP.
You can use all fiile modes. I do not quite understand your problem.
The file modes are NOT as you are using, but predefined in classes unit.
The start with fm. You are mixing up API calls with fpc calls.

See, as usual!, the MANUAL?
https://www.freepascal.org/docs-html/rtl/classes/tfilestream.create.html
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

Atak_Snajpera

  • New Member
  • *
  • Posts: 31
Re: TFileStream.Create requires MODE in Lazarus
« Reply #5 on: June 01, 2024, 03:46:06 pm »
Quote
I do not quite understand your problem.
My problem was that code which works in DELPHI 7 does not compile in LAZARUS with those

Code: Pascal  [Select][+][-]
  1. Stream: TFileStream;
  2. Stream:=TFileStream.Create(FileHandle);

With THandleStream it compiles and program works fine

Code: Pascal  [Select][+][-]
  1. Stream: THandleStream;
  2. Stream:=THandleStream.Create(FileHandle);


Attached full source code
« Last Edit: June 01, 2024, 03:50:01 pm by Atak_Snajpera »

Thaddy

  • Hero Member
  • *****
  • Posts: 18676
  • Jungle wars. And failing health it seems.
Re: TFileStream.Create requires MODE in Lazarus
« Reply #6 on: June 01, 2024, 04:16:50 pm »
I could not download it because of the included exe in the 7z file. Reports a - possibly false - virus.
Can you just 7z the sources?

BTW in Delphi7 those constants map exactly to the WinApi ones.
Actually that code was wrong anyway, but it works because of that.
(Yes, I have a running D7 on WIN11 )
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

wp

  • Hero Member
  • *****
  • Posts: 13334
Re: TFileStream.Create requires MODE in Lazarus
« Reply #7 on: June 01, 2024, 04:44:52 pm »
My problem was that code which works in DELPHI 7 does not compile in LAZARUS with those

Code: Pascal  [Select][+][-]
  1. Stream: TFileStream;
  2. Stream:=TFileStream.Create(FileHandle);
Then you must be doing something unusual. Do you use some third-party units which override the declaration of TFileStream? In which unit/library is the "TWorkerThread" that is mentioned in the initial post?

This is from the "classes" unit of Delphi 7:
Code: Pascal  [Select][+][-]
  1.   TFileStream = class(THandleStream)
  2.   public
  3.     constructor Create(const FileName: string; Mode: Word); overload;
  4.     constructor Create(const FileName: string; Mode: Word; Rights: Cardinal); overload;
  5.     destructor Destroy; override;
  6.   end;

Atak_Snajpera

  • New Member
  • *
  • Posts: 31
Re: TFileStream.Create requires MODE in Lazarus
« Reply #8 on: June 01, 2024, 06:02:53 pm »
I could not download it because of the included exe in the 7z file. Reports a - possibly false - virus.
Can you just 7z the sources?

BTW in Delphi7 those constants map exactly to the WinApi ones.
Actually that code was wrong anyway, but it works because of that.
(Yes, I have a running D7 on WIN11 )

Try now.

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1570
    • Lebeau Software
Re: TFileStream.Create requires MODE in Lazarus
« Reply #9 on: June 01, 2024, 07:43:32 pm »
What value should I use for MODE?

Nothing, because you are not calling the constructor that takes a Mode parameter.  That parameter is only for when you pass in a file name, not a pre-existing handle.

Delphi 7 code
...

That code is wrong.  It should be creating a THandleStream, not a TFileStream.  The sole purpose of TFileStream is to accept a file name as input (and expose that file name in the FileName property). But since this code is not passing in a file name to the stream, then TFileStream is simply the wrong class to use.

Now Lazarus requires also a MODE.

Only when calling the constructor that accepts a file name.  Delphi allows calling ancestor constructors if they are public.  The code you showed passing a file handle to the TFileStream's ancestor constructor still compiles in modern Delphi versions.  Why FreePascal/Lazarus is rejecting it, who knows, but its probably a good thing in this case.
« Last Edit: June 01, 2024, 08:01:07 pm by Remy Lebeau »
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

 

TinyPortal © 2005-2018