I want to report a TFileStream error

constructor TFileStreamDesenant.Create(const AFileName: string);
begin
  FHandle := FileCreate(AFileName);
  FileClose(FHandle);
  inherited Create(AFileName, fmOpenReadWrite or fmExclusive);

I could not get TFileStream to open a new file so I wrote the above code
of course the fmOpenReadWrite should have opened the file and was an unnecessary bug that I did not need.

A couple of things - you’ve not really asked a question here, have you? You’re making a statement. To get better answers it’s important to ask better questions.

Secondly, you’re not really understanding how the file handling flags work. Also, your code above will throw an exception (error) if the file already exists.

The most common pattern is this:

var FS: TFileStream;
if FileExists(thefile) then
  FS := TFileStream.Create(thefile, fmOpenReadWrite or fmExclusive)
else
  FS := TFileStream.Create(thefile, fmCreate or fmExclusive);

You can optimize that in various ways but, really, that’s the pattern.

TFileStream should be a basic common Delphi object to use
But it simply is not working under the conditions I have why?
Is it something to do with fmOpenReadWrite or fmExclusive
below is the TFileStream out of the classes unit
is it something to do with LShareMode

constructor TFileStream.Create(const AFileName: string; Mode: Word; Rights: Cardinal);
var
  LShareMode: Word;
begin
  if (Mode and fmCreate = fmCreate) then
  begin
    LShareMode := Mode and $FF;
    if LShareMode = $FF then
      LShareMode := fmShareExclusive; // For compat in case $FFFF passed as Mode
    inherited Create(FileCreate(AFileName, LShareMode, Rights));
    if FHandle = INVALID_HANDLE_VALUE then
      raise EFCreateError.CreateResFmt(@SFCreateErrorEx, [ExpandFileName(AFileName), SysErrorMessage(GetLastError)]);
  end
  else
  begin
{$IFDEF MSWINDOWS}
    inherited Create(FileOpen(AFileName, Mode));
{$ELSE !MSWINDOWS}
                                                                              
    inherited Create(FileOpen(AFileName, Mode));
{$ENDIF MSWINDOWS}
    if FHandle = INVALID_HANDLE_VALUE then
      raise EFOpenError.CreateResFmt(@SFOpenErrorEx, [ExpandFileName(AFileName), SysErrorMessage(GetLastError)]);
  end;
  FFileName := AFileName;
end;

Lex,

If you really want help, please, do include enough information around the questions to understand what you are seeing and the problem you are experiencing. Show your code that uses TFileStream and tell us what your “conditions” are.

We CANT see your screen or read your mind.

Sorry TFileStream under these settings
1/ me opening a file directly with MS code to make the new file
2/ a file is not opened to access the hard drive
This is TFileStream and its not working at all
This is TFileStream and its not working at all
I put TMemoryStream in its place and it works just fine
Do I need to use
function FileOpen(const FileName: string; Mode: LongWord): THandle;
and forget TFileStream all together

Did you see Ian’s response? Is there a reason you can’t use his TFileStream example?

explain how is their a conflict with ‘fmOpenReadWrite or fmExclusive’
the windows file system should handle that as it has in the past
1/ fmOpenReadWrite is full access rights to the data in the file
2/ fmExclusive stops anything else touching the file data
3/ or statement joins the flags correctly
So what is wrong?

The main thing wrong is that questions sorta get asked, but there is still no demonstration of exactly how the TFileStream is being used, exactly what scenario we are looking at (file exists? create new?), or what problems are actually observed (error messages? result codes?! Anything at all?)

Try to consider the readers when creating these threads. Others know nothing about your code, errors, etc and thus its important to include all relevant details.

1 Like

I’m using FileDialog for the user to ether select a already made file or a new one
even already created new file - TFileStream will not make the connection at all
nothing
nothing
nothing
its effectively a dead object!!!
I use the TFileStream.read and TFileStream.Write and I set the position before read/writing an entire TMemory Stream using TMemoryStream.Memory^ and TMemoryStream.Size
I’m loading *.Jpg pictures strait into a memory stream decompressing and displaying with TImage on my form with no issues then taking the TMemoryStream to TFileStream with set allocated space for the save but when recalled from file - the picture is not their at all. Noting saved is recallable from file at all - not even saving a integer and recalling it. And it will not open a file with a fmOpenReadWrite flag.
its dead dead dead!!!
The handle error message is not even an error or a windows file handle
I have made a descendant of TFileStream as the first piece of code shows at the top
I’m not even getting out a file named with no data on the create as I have to use FileCreate(AFileName) to make a file name that is not part of TFileStream.
I’m not using ‘rights’ as its a single thread TFile is not making a file
J Lex Dean

1 Like
unit System.SysUtils;

  fmOpenRead       = $0000;
  fmOpenWrite      = $0001;
  fmOpenReadWrite  = $0002;
  fmExclusive      = $0004; // when used with FileCreate, atomically creates the file only if it doesn't exist, fails otherwise

  fmShareCompat    = $0000 platform; // DOS compatibility mode is not portable
  fmShareExclusive = $0010;
  fmShareDenyWrite = $0020;
  fmShareDenyRead  = $0030 platform; // write-only not supported on all platforms
  fmShareDenyNone  = $0040;

Now hear is the whys???
You have fmOpen but not fmCreate and not fmOpenCreate
You do not have the Flags needed for TFileStream
a fmCreate would mean code in TFileStream,Create to contain

If fileExists(AFileName)  and (mode and fmCreate = fmCreate) 
    then FileCreate(AFileName)  
    else FileIOpen(AFileName) 

why do I not see this type of code in TFileStream to be RAD!!!

Have you looked at the example of TFileStream in the documentation?

https://docwiki.embarcadero.com/CodeExamples/Athens/en/ZLibCompressDecompress_(Delphi)

not that one but what good is it to me - i do not even want compression
I mite as well go to low level windows where I have one layer to learn not 3 layers like that. I want RAD straight forward file access where the file access has been organized
just set the flags a its their and dependable.
I have written 400 lines a tested code to only totally rewrite it because TFileStream does not work - it cannot tell me did not get file access cannot create a file basic staff.

Why don’t you create an object descended from THandleStream (like TFileStream is) and have it open/create the file how you want it done?

In your initial post, I interpret your request that you want to open the file, even if it doesn’t exist. If that is the case, then you would need to call WinApi.Windows.CreateFile with the fifth parameter as OPEN_ALWAYS. This page has all the information you need for all the parameters to the CreateFile call - CreateFileW function (fileapi.h) - Win32 apps | Microsoft Learn

While Delphi has a lot of nice features that can be used out of box, it can’t have everything and sometimes you need to implement it yourself. But this is the beauty of Delphi - you are not restricted to what is given to you. You can make what you want/need.

The main problem here is still that you are not showing any code of your own.

Create the smallest example possible (eg console app) demonstrating usage of TFileStream that doesn’t work, post here for comment. Then we have something to work from.

BTW, something like this does work - this is straight out of the VCL

Stream := TFileStream.Create(FileName, fmCreate);


NickR
Nicholas Ring

MS’s CreateFileW function that is complicated for me to get my head around
Give me time I have been thinking below

Delphi could easily added a flag/Mode with fmOpen and fmCreate

I totally agree with you that a better rewrite of TFileStream from THandle is a very good idea the only thing - its not able to be Linux tested by me.
And that is exactly what a Delphi programmer wants is the objects to have already figured out all this back ground in and out staff to give versatility or RAD.
Instead they are not getting out of C++ where you have 10 times more code that the code needs extensive documenting because you get lost in your own code.
We got to see the wood in the trees and not get lost with unnecessities.

Many forums reject fmExclusive for some reason?
This ‘rights’ value for multi threading has no documentation so is a
‘STANDARD_RIGHTS_REQUIRED’ ok?
I only want a single thread without other application interference
I need System.SysUtils i see
but I do like ‘Position’ of TStream that building from THandle is good
I wish TStream used the words ‘Load’ and ‘save’ to remove confusion that you have with ‘read’ and ‘Write’ because you do not know where the data is going to and why so many .‘read’ and ‘Write’ overloads as Delphi pointers have never been that defined. One of the main problems is pointers do not define clearly as you jump in and out of pointers and values automatically taking control away from the programmer. A Pointer Needs to be a pointer until the '^" is placed on it and ‘@’ needs to make a pointer and not the code smizing a change! and what you do under ‘Types’ you should be doing in Code and VAR

constructor TMyFileStream.Create(const AFileName: string);
begin
If FileExists(AFileName)
 then FHandle := FileOpen(AFileName, fmOpenReadWrite or fmShareDenyWrite, 0)
 else FHandle := FileCreate(AFileName, fmOpenReadWrite or fmShareDenyWrite);


my check in another function
if FHandle <> INVALID_HANDLE_VALUE then

TStream is some of the heart of Delphi but when that is not right it has an effect

Another thing TFileStream should never deliver a FileName if it never obtains a file handle from windows for that name!!!

TFilestream doesn’t ‘deliver’ a filename, you provide one, it acts on it.

it records the file name with a function to recall it
but what’s the point of it being recalled if the file was never opened in the first place
and to use FHandle to work out how to use THandle why use TFileStream at all
if it does not open the file so removing access to the file name is a simple way to say it is not connected to a file.

what is more important is a set up to getting
1/ a file Created if its needed
2/ opened
3/ if something is blocking access a) another application b) user rights
4/ the capacity to exclude other apps with different access types
5/ default settings is optional
6/ android and windows compatible
other objects can use TFileStream if they choose

MS’s CreateFileW function that is complicated for me to get my head around

Use what is in the VCL to clear things up. Some of the parameters aren’t used within the VCL (like the security params). The rest can be used with System.SysUtils.FileCreate to see how it is used.

Delphi could easily added a flag/Mode with fmOpen and fmCreate

There is nothing stopping you to raise a request for it. But personally, I think a developer could write a library for this and let E get on with stuff that developers can not do… Just saying.

This ‘rights’ value for multi threading has no documentation so is a
‘STANDARD_RIGHTS_REQUIRED’ ok?

Rights value is not used for Windows, so it can be anything you like. For non-Windows, then it is the last parameter of the __open method, which happens to be a C library function.

Pointers

This is what makes Delphi so powerful.